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.
Related
- (void)viewDidLoad
{
[super viewDidLoad];
m_allFriends = [[NSMutableArray alloc] init];
if ([[FBSession activeSession] isOpen])
{
if ([[[FBSession activeSession] permissions]indexOfObject:#"user_friends"] == NSNotFound)
{
[[FBSession activeSession] requestNewPublishPermissions:[NSArray arrayWithObject:#"user_friends"] defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,NSError *error){
[self getFBFriendListFunc];
NSLog(#"1");
}];
}
else
{
[self getFBFriendListFunc];
NSLog(#"2");
}
}
else
{
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"user_friends"]
defaultAudience:FBSessionDefaultAudienceOnlyMe
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
[self getFBFriendListFunc];
NSLog(#"3");
}else{
NSLog(#"error");
}
}];
}
}
-(void)getFBFriendListFunc
{
[FBRequestConnection startWithGraphPath:#"me/friends"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#"me/friends result=%#",result);
NSLog(#"me/friends error = %#", error.description);
NSArray *friendList = [result objectForKey:#"data"];
[m_allFriends addObjectsFromArray: friendList];
}];
}
I try to connect Facebook with their API, actually this code connect Facebook, Facebook ask me this application want to use your information than i confirmed. Last step, Facebook return again my application than this getFBFriendListFunc should be run but none of if/else work. Nothing display...
I get this codes on Facebook developer which code part wrong ?
Any idea ?
Thank you...
For inviting users you can use the following code after adding the facebook-sdk
[FBWebDialogs
presentRequestsDialogModallyWithSession:sharedFacebookHelper.session
message:#"Your invite message"
title:nil
parameters:nil
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
NSLog(#"Error publishing story: %#", error.description);
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User canceled.
NSLog(#"User cancelled.");
} else {
// Handle the publish feed callback
}
}
}];
I add this function on AppDelegate.m if this function does not exit login session never be work i hope this code help any one :)
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
return wasHandled;
}
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 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
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 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.