I am in trouble with parse user`s email. I can take from user almost everything though fb graph api. But it does not contain email property. Any idea, how to get it? If I do NSlog it always returns null.
{
NSArray *permissionsArray = #[#"email", #"basic_info"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
// Was login successful ?
if (!user) {
if (!error) {
NSLog(#"The user cancelled the Facebook login.");
}else {
NSLog(#"An error occurred: %#", error.localizedDescription);
}
// Callback - login failed
if ([delegate respondsToSelector:#selector(commsDidLogin:)]) {
[delegate commsDidLogin:NO];
}
}else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary<FBGraphUser> *prop = (NSDictionary<FBGraphUser> *)result;
NSDictionary *userData = (NSDictionary *)result;
[[PFUser currentUser] setObject:prop.id forKey:#"fbid"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.first_name forKey:#"firstname"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.last_name forKey:#"lastname"];
[[PFUser currentUser] saveInBackground];
NSString *mail = userData[#"email"];
[[PFUser currentUser] setObject:mail
forKey:#"email"];
[[PFUser currentUser] saveInBackground];
NSLog(#"prop %#", prop);
}else {
NSLog(#"User logged in through Facebook!");
NSLog(#"Welcome Screen I am %#", [[PFUser currentUser] username]);
}
}];
}
else {
//HERE
NSLog(#"Error getting the FB username %#", [error description]);
}
[[PFUser currentUser] saveInBackground];
// Callback - login successful
if ([delegate respondsToSelector:#selector(commsDidLogin:)]) {
[delegate commsDidLogin:YES];
}
}];
}
Not every Facebook user exposes the same information as part of their public profile, the email field is one in particular where you need to accept that this will often NOT be exposed.
The userData NSDictionary you get back will only be populated with information the person has made public, so handle missing keys as needed per user.
Documentation to read:
Requesting permissions
Reading the user's information
Related
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 want to give my user the ability to remove their account, thus not showing up in the feeds of other users.
One way I could do this is adding an 'active' column to the 'User' table.
A better way would be to remove their User object from the table. Unfortunately, when I implement code to do so, the app crashes and the following error shows up: 'User cannot be deleted unless they have been authenticated via logIn or signUp'.
Maybe something is wrong with my login code.
NSArray *permissionsArray = #[#"email", #"public_profile", #"user_friends"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oops, error" message:#"Couldn't login at the moment. Try again later." delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
}
}
else {
// Send request to Facebook
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// handle response
if (!error) {
// Parse the data received
NSDictionary *userData = (NSDictionary *)result;
[[PFUser currentUser] setObject:[NSNumber numberWithLongLong:[userData[#"id"] longLongValue]] forKey:#"facebook_id"];
[[PFUser currentUser] setObject:userData[#"name"] forKey:#"name"];
[[PFUser currentUser] saveInBackground];
// Go to home screen here
}
}];
}
}];
Deleting is done like this:
PFObject *userObject = [PFObject objectWithoutDataWithClassName:#"_User" objectId:[PFUser currentUser].objectId];
[userObject deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// back to login view controller
}];
Any idea how to fix this?
Why are you re-fetching the user object when you already have it as [PFUser currentUser]? Perhaps you need to delete the [PFUser currentUser] object directly? Something like:
[[PFUser currentUser] deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// back to login view controller
}];
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
I am using Parse and I want to show email taken from Parse and display in column in Parse. Everything like first_name, last_name, id etc. works fine. But when I try to set prop.email it doesn't find any property. If I do the same action in the place (tagged in the code), it finds me email property without any problems.
I mean this line of code:
[[PFUser currentUser] setObject:prop.id forKey:#"fbid"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.first_name forKey:#"firstname"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.last_name forKey:#"lastname"];
[[PFUser currentUser] saveInBackground];
//This one doesn`t find property email
[[PFUser currentUser] setObject:prop.email forKey:#"email"];
[[PFUser currentUser] saveInBackground];
The rest of FB connect`code
{
NSArray *permissionsArray = #[#"email"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
// Was login successful ?
if (!user) {
if (!error) {
NSLog(#"The user cancelled the Facebook login.");
}else {
NSLog(#"An error occurred: %#", error.localizedDescription);
}
// Callback - login failed
if ([delegate respondsToSelector:#selector(commsDidLogin:)]) {
[delegate commsDidLogin:NO];
}
}else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary<FBGraphUser> *prop = (NSDictionary<FBGraphUser> *)result;
[[PFUser currentUser] setObject:prop.id forKey:#"fbid"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.first_name forKey:#"firstname"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.last_name forKey:#"lastname"];
[[PFUser currentUser] saveInBackground];
[[PFUser currentUser] setObject:prop.email forKey:#"email"];
[[PFUser currentUser] saveInBackground];
}else {
NSLog(#"User logged in through Facebook!");
NSLog(#"Welcome Screen I am %#", [[PFUser currentUser] username]);
}
}];
}
else {
//HERE
NSLog(#"Error getting the FB username %#", [error description]);
}
[[PFUser currentUser] saveInBackground];
// Callback - login successful
if ([delegate respondsToSelector:#selector(commsDidLogin:)]) {
[delegate commsDidLogin:YES];
}
}];
}
Your code generates a compile error because email is not defined in the FBGraphUser protocol. So, you will need to find a different way to get the user e-mail from Facebook.
If you're using PFSignUpViewController and then later linking the account, ensure that the user enters an e-mail at that point in time.
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"];
}
}
}];