So I finally got my app letting users sign into Facebook and parse. Lets call my app a game even though it isn't and lets say that I upload the newest score someone gets every time they play the game. So what I have done is uploaded the "score" to parse under the user. Now, I want the user to be able to see friends that are on Facebook's score. So, I have the user signed in and now how can I check if their friend is using my "game" and then match their email with the one on parse to get there score? As of now, I can get the friends id's of the user that signed in.
BTW. the user has to sign into facebook and make a parse account for my app
I know I am gong to have to use a query to get stuff from parse, I guess my main question is How do I get the facebook users email?
This is how I am getting their id :
- (void)getFacebookInfo {
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Set user's information
NSString *facebookId = [result objectForKey:#"id"];
NSString *facebookName = [result objectForKey:#"name"];
if (facebookName && facebookName.length != 0) {
[[PFUser currentUser] setObject:facebookName forKey:#"displayName"];
}
if (facebookId && facebookId.length != 0) {
[[PFUser currentUser] setObject:facebookId forKey:#"facebookId"];
}
[[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// Get user's friend information
[FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSArray *data = [result objectForKey:#"data"];
NSMutableArray *facebookIds = [[NSMutableArray alloc] initWithCapacity:data.count];
for (NSDictionary *friendData in data) {
[facebookIds addObject:[friendData objectForKey:#"id"]];
}
[[PFUser currentUser] setObject:facebookIds forKey:#"facebookFriends"];
[[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// We're in!
NSLog(#"%#", facebookName);
[self dismissViewControllerAnimated:YES completion:NULL];
}];
} else {
[self showErrorAlert];
}
}];
}];
} else {
[self showErrorAlert];
}
}];
}
In order to get the email address of the Facebook user within the completion handler of startForMyFriendsWithCompletionHandler use:
[FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSArray *data = [result objectForKey:#"data"];
for (NSDictionary *friendData in data) {
//This is each friend's email address
NSString *aFriendsEmail = [friendData objectForKey:#"email"];
}
}
}];
Related
This question already has answers here:
Facebook JS SDK's FB.api('/me') method doesn't return the fields I expect in Graph API v2.4+
(4 answers)
Closed 7 years ago.
I am using parse framework to manage users.
I have an option in my app where the users can login from facebook.
I have linked the FacebookAppID and URL scheme in plist file.
According to parse documentation the recommended code here is below
[PFFacebookUtils logInWithPermissions:#[ #"email",#"user_about_me", #"user_relationships", #"user_birthday", #"user_location"] block:^(PFUser *user, NSError *error)
{
if (user)
{
NSLog(#"User authenticated from facebook.");
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error)
{
NSLog(#"Facebook id fetched.");
// result is a dictionary with the user's Facebook data
NSDictionary *userData = (NSDictionary *)result;
}
}
else
{
// User not authenticated
}
]];
Now as you can see i have entered proper permissions for email,user_about_me,user_relationships,user_birthday, user_location
But the result dictionary i am getting from facebook only return name and id everytime and for every user.
I also want rest of the information. Any one know why i am not getting all user data?
Its not duplicate
Use this code-
-(void)fectchUserInfo
{
FBRequest *req = [[FBRequest alloc] initWithSession:[FBSession
activeSession] graphPath:#"me?
fields=first_name,last_name,gender,id,email"];
[req startWithCompletionHandler:^(FBRequestConnection *connection, id result,NSError *error) {
if(error) {
NSLog(#"fb error");
[self handleAuthError:error];
return;
}
else{
facebookFirstName = [result objectForKey:#"first_name"];
facebookLastName = [result objectForKey:#"last_name"];
facebookID = [result objectForKey:#"id"];
facebookEmail = [result objectForKey:#"email"];
NSLog(#"fb data:%# %# %# %# ",facebookFirstName,facebookLastName,facebookID,facebookEmail);
facebookPassword = [NSString stringWithFormat:#"%#_%#",facebookID,#"fb"];
NSLog(#"fb password is :%#",facebookPassword);
}
}];
}
I am using Parse as my database. I want to access the _Users class to see if my Facebook friends are using the app (in the class _User). I have just read this and found out that you can't save friendlist anymore.
The way I did it so far is:
I first get the FB ids of my friends and query it in _User. However, I noticed that the FacebookIDs are saved as authData. How can I query my _User class using FacebookIDs besides creating a new column duplicating facebookIDs as strings?
// Send request to Facebook
[[FBRequest requestForMe] startWithCompletionHandler: ^(FBRequestConnection *connection, id result, NSError *error) {
[FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// result will contain an array with your user's friends in the "data" key
NSArray *friendObjects = [result objectForKey:#"data"];
NSMutableArray *friendIds = [NSMutableArray arrayWithCapacity:friendObjects.count];
// Create a list of friends' Facebook IDs
for (NSDictionary *friendObject in friendObjects) {
[friendIds addObject:[friendObject objectForKey:#"id"]];
}
self.fbfriendList = [NSMutableArray arrayWithArray:friendObjects];
PFQuery *friendQuery = [ParseUser query];
//PROBLEM is here where the fbId in my _User class is saved as authData
[friendQuery whereKey:#"fbID" containedIn:friendIds];
NSArray *friendUsers = [friendQuery findObjects];
self.fbfriendList = friendObjects;
}
}];
}];
Parse Users' Facebook IDs are private by default, but you can make them accessible from other users.
To accomplish this, you can use the Facebook API to get the user's Facebook ID, assign it to a field on the Parse User. Then you can construct a query on the User collection to get a list of Parse users whose Facebook IDs are in your user's friend list.
When you do your Login with Facebook, you should do it like this:
// When your user logs in, immediately get and store its Facebook ID
[PFFacebookUtils logInWithPermissions:permissionsArray
block:^(PFUser *user, NSError *error) {
if (user) {
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Store the current user's Facebook ID on the user
[[PFUser currentUser] setObject:[result objectForKey:#"id"]
forKey:#"fbId"];
[[PFUser currentUser] saveInBackground];
}
}];
}
}];
Then, when you are ready to search for your user's friends, you would issue another request:
// Issue a Facebook Graph API request to get your user's friend list
[FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// result will contain an array with your user's friends in the "data" key
NSArray *friendObjects = [result objectForKey:#"data"];
NSMutableArray *friendIds = [NSMutableArray arrayWithCapacity:friendObjects.count];
// Create a list of friends' Facebook IDs
for (NSDictionary *friendObject in friendObjects) {
[friendIds addObject:[friendObject objectForKey:#"id"]];
}
// Construct a PFUser query that will find friends whose facebook ids
// are contained in the current user's friend list.
PFQuery *friendQuery = [PFUser query];
[friendQuery whereKey:#"fbId" containedIn:friendIds];
NSArray *friendUsers = [friendQuery findObjects];
}
}];
Best regards,
I'm building an app on iOS using Parse as a backend.
Doing so I use the Parse Facebook SDK in order first to link Facebook to my Parse User and then to query his data and save them.
The Problem is: sometimes I don't get some of the info like eMail (userData[#"email"] is nil), first_name,name .., or the Profile Pic doesn't download.
Not all the time (quite rare actually), and impossible to reliably replicate the issue so I can solve it. And it's often only one missing field not all.
So I got holes in my Database (not cool when it is the user's email address: my main concern)
Here is how I wrote my methods (i edited most of the if(error) management to make it shorter).
Any ideas ?
Thank you guys !
NSArray *permissionsArray = #[#"public_profile",#"email", #"user_friends"];
[PFFacebookUtils initializeFacebook];
// Login PFUser using Facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
[self fbData:self];
} else {
NSLog(#"User with facebook logged in!");
[self fbDataAlreadyLog:self];
}
}];
Then I call my "fbData" function in order to fill in the user data into Parse:
-(IBAction)fbData:(id)sender{
[PFFacebookUtils initializeFacebook];
FBRequest *request = [FBRequest requestForMe];
// Send request to Facebook
[request startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *userCloud, NSError *error) {
if (!error) {
// result is a dictionary with the user's Facebook data
NSDictionary *userData = userCloud;
NSString *facebookID = userData[#"id"];
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large&return_ssl_resources=1", facebookID]];
PFUser *user = [PFUser currentUser];
if (userData[#"name"]) {
user[#"name"] = userData[#"name"];
}
if (userData[#"first_name"]) {
user[#"first_name"] = userData[#"first_name"];
}
if (userData[#"last_name"]) {
user[#"last_name"] = userData[#"last_name"];
}
if (userData[#"id"]) {
user[#"fbID"] = userData[#"id"];
}
if (userData[#"gender"]) {
user[#"gender"] = userData[#"gender"];
}
if (userData[#"email"]) {
user.email = userData[#"email"];
user.username = userData[#"email"];
}
if (userData[#"age_range"]) {
user[#"age_range"] = userData[#"age_range"];
}
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:pictureURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize)
{
// progression tracking code
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished,NSURL *imageURL)
{
if (image)
{
// do something with image
NSData *imageNSData = UIImagePNGRepresentation(image);
PFFile *imageFile = [PFFile fileWithName:#"profilePic" data:imageNSData];
user[#"image"] = imageFile;
[user saveInBackgroundWithBlock];
//Once the Save Block is done I managed a few more thing before moving on to the next ViewController
}
}];
}];
try like this
NSArray *permissionsArray = #[ #"user_about_me", #"user_relationships", #"user_birthday", #"user_location"];
How can I fetch all informations about my friends with graph API ?
Here is my code :
LoginViewController.m (ViewController) :
- (IBAction)loginButtonTouchHandler:(id)sender
{
// Set permissions required from the facebook user account
NSArray *permissionsArray = #[#"public_profile", #"email", #"user_friends", #"user_birthday", #"friends_birthday"];
// Login PFUser using facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (user) {
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
[self.navigationController popToRootViewControllerAnimated:YES];
// Store the current user's Facebook ID on the user
[[PFUser currentUser] setObject:[result objectForKey:#"email"]
forKey:#"email"];
[[PFUser currentUser] setObject:[result objectForKey:#"name"]
forKey:#"name"];
[[PFUser currentUser] saveInBackground];
}
}];
}
}];
}
CalendarViewController.m (UITableViewController) :
- (void)viewDidLoad
{
[super viewDidLoad];
[FBRequestConnection startWithGraphPath:#"/me/friends"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
if (!error) {
// Success! Include your code to handle the results here
NSLog(#"user info: %#", result);
} else {
NSLog(#"problem");
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
Here is my NSLog :
"2014-08-08 22:55:16.615 Mindle[803:60b] user info: {
data = (
);
summary = {
"total_count" = 779;
};
}"
That counts my friends, but is there any solution for fetching their birthday_date ?
In API v2.0 or later you can not access your friends birthdays.
I am giving to my users the options to sign up manually or using Facebook(I am using Parse). The problem now is that if a user has signup manually and then try to login with Facebook is creating a second account and leaves the email valun to null(becuase already exists). So what is the solution for this one? Is there any official solution? I tried a workaround:
FBRequest *requestEmail = [FBRequest requestForMe];
[requestEmail startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"Error %#",error);
NSDictionary *userData2 = (NSDictionary *)result;
NSString *email2=userData2[#"email"];
PFQuery *query = [PFUser query];
[query whereKey:#"email" equalTo:email2];
[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
NSString *emailQue =[object objectForKey:#"email"];
if(error || (emailQue==NULL) || (emailQue==nil)){
NSLog(#"User facebook account does not exist");
}
else{
NSLog(#"User facebook email exist");
NSLog(#"email %#",emailQue);
}
}];
}];
which is failing (No active token available) and I believe this is not the correct way. Even if this work then I cant stop the loginWithPermission to create the new user once canceled.
Any suggestions?
If you know that this user is an existing PFUser you can instead link their Facebook account with their existing account. This is a supported Parse feature.
if (![PFFacebookUtils isLinkedWithUser:user]) {
[PFFacebookUtils linkUser:user permissions:nil block:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(#"Woohoo, user logged in with Facebook!");
}
}];
}
You can get the current user with
PFUser *currentUser = [PFUser currentUser];
Or you could even convert an Anonymous user to a Facebook user.
https://parse.com/docs/ios_guide#fbusers-link/iOS