ViewController doesn`t display property FB/Parse - 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.

Related

Fetching all friend's birthday in Facebook iOS 7

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.

FBRequestConnection startForMeWithCompletionHandler - NSInvalidArgumentException

I can't seem to call the FBRequestConnection startForMeWithCompletionHandlerwithout it throwing an exception.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't use nil for keys or values on PFObject. Use NSNull for values.'
this used to work without any problem. But then I deleted the "User" objects in my parse table. Now whenever I try to login, the new user gets created in the parse table and I get the log message that the user is logged in. but when I want to call the FBRequestConnection function to retrieve the facebook id of the user I get the error.
- (id) init {
if (self == [super init]) {
[PFFacebookUtils initializeFacebook];
sharedHelper = self;
}
return self;
}
- (void) authenticateUserWithFacebook {
NSArray *permissionsArray = #[#"user_relationships",#"user_friends",#"read_friendlists"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
if (!error) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else {
NSLog(#"Uh oh. An error occurred: %#", error);
[[PFFacebookUtils session] closeAndClearTokenInformation];
[[PFFacebookUtils session] close];
[[FBSession activeSession] closeAndClearTokenInformation];
[[FBSession activeSession] close];
[FBSession setActiveSession:nil];
[PFUser logOut];
}
} else if (user.isNew) {
NSLog(#"User with facebook signed up and logged in!");
UIApplication *application = [UIApplication sharedApplication];
[application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[[PFUser currentUser] setObject:[result valueForKey:#"id"] forKey:kFbIdKey];
[[PFUser currentUser] setObject:[result valueForKey:#"name"] forKey:#"name"];
[[PFUser currentUser] saveInBackground];
}];
} else {
NSLog(#"User with facebook logged in!");
UIApplication *application = [UIApplication sharedApplication];
[application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[[PFUser currentUser] setObject:[result valueForKey:#"id"] forKey:kFbIdKey];
[[PFUser currentUser] setObject:[result valueForKey:#"name"] forKey:#"name"];
[[PFUser currentUser] saveInBackground];
}];
}
}];
}
I think I've solved the issue using [FBSession renewSystemCredentials:]
and also removing and reinstalling the app. I think the fact that I also deleted Installationobjects also was related to the issue.

Parse receive E-mail FB SDK

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

Delete [PFUser currentUser] after Facebook login

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
}];

Parse - Users trying to login with FB after creating account manual - iOS

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

Resources