Parse: [PFFacebookUtils reauthorizeUser:] callback never gets called - ios

I'm using the Parse framework for social authentication. My app has a really simple method that requests post permission on Facebook.
My problem: The block that I pass into reauthorizeUser: never gets called!
+(void)acquirePublishPermissionsForUser:(DHUser *)user WithCompletion:(void (^) (BOOL succeeded, NSError *error))completion
{
[PFFacebookUtils reauthorizeUser:user
withPublishPermissions:#[#"publish_actions"]
audience:FBSessionDefaultAudienceFriends
block:^(BOOL succeeded, NSError *error) {
completion(succeeded, error);
}];
}
This method works fine. In this case, the Facebook app opens up and prompts for permission. Upon hitting OK, you're returned to my app. Both openURL & applicationDidBecomeActive get called.
This is in my app delegate:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// Handle Facebook authentication
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:[PFFacebookUtils session]];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Handle Facebook Authentication
[FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
}
I've set a breakpoint to verify: my block never gets executed. It's really important, because I want to post to Facebook after I get permission. Otherwise it's kinda useless.
Any ideas?

I ended up using a straight FB-API call ([[FBSession activeSession] requestNewPublishPermissions]).
It does weird stuff with my session and auth token data, but at least the callback gets executed. Definitely not a real solution but it'll do.

Related

'user' is always nil in logInInBackgroundWithReadPermissions in Parse iOS SDK

I'm using Facebook SDK with Parse SDK in user Login.
Using 'logInInBackgroundWithReadPermissions' to perform login, Even though user is authenticated the app, 'user' is always nil in the response. And error is:
Error Domain=com.facebook.sdk.login Code=304 "The operation couldn’t
be completed. (com.facebook.sdk.login error 304.)"
Here is my Implementation:
• Basic configuration:
I have configured every thing in .plist
and followed guidelines at link1, link2
• Imported frameworks:
• Implementation in Appdelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[Parse setApplicationId:#"I have used real key here" clientKey:#"I have used real key here"];
[PFFacebookUtils initializeFacebookWithApplicationLaunchOptions:launchOptions];
return YES; }
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
• Login Implementation:
NSArray *fbPermissions = [[NSArray alloc] initWithObjects: #"public_profile", nil];
[PFFacebookUtils logInInBackgroundWithReadPermissions:fbPermissions block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
}
else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
} else {
NSLog(#"User logged in through Facebook!");
}
}];
But in the call back, 'user' is always nil. Did anyone face the same issue?
- Thanks in advance.
I was not able to find out cause for the issue. But I just deleted all frameworks related to Parse and Facebook and Re-added all of them. It worked fine. So, there is no issue in the code.
in AppDelegate.m file, under didFinishLaunchingWithOptions method, initialize Parse before initializing PFFacebookUtils.

Facebook login crashes on cold starts

I have a little trouble when implementing new Facebook Login for our app. We are using Facebook SDK v4.3 for our development. And the login/signup process crashes on devices with low memory. We suspect that the low memory constraints have caused our app to terminate when it triggered a switch to Facebook for authentication. As document in the Facebook's old SDK (link https://developers.facebook.com/docs/facebook-login/ios#login-apicalls):
Login flows require an app switch to complete, it's possible your app gets terminated by iOS in low memory conditions or if your app does not support backgrounding.
In that case, the state change handler supplied to your open call disappears.
To handle that scenario explicitly assign a state change handler block to the FBSession instance any time prior to the handleOpenURL: call:
// During the Facebook login, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
// Note this handler block should be the exact same as the handler passed to any open calls.
[FBSession.activeSession setStateChangeHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// Retrieve the app delegate
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
}];
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
Unfortunately, the new Facebook SDK deprecated FBSession.activeSession and its stateChangeHandler. I followed the custom UI FBLogin button for my app, here is my appDelegate code
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
The code works fine and executes perfectly under normal condition. However, it behave oddly under cold starts (due to low memory). So my question would be: How do we prevent this? Is there an equivalent handler for the new SDK?
PS. I did my job in managing the device's memory. But it still didn't work under this stressed conditions.
Edit: All I want is to grab the user's basic information on success. Therefore, I did not need keep track (or have the need to) of the access token. This is the block of code that I use to invoke login
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:#[#"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
[ErrorMessageDisplay displayErrorAlertOnViewController:self withTitle:FB_LOGIN_ERROR_TITLE andMessage:FB_LOGIN_ERROR_MESSAGE];
[self.loginView enableLoginButtons];
} else if (result.isCancelled) {
[ErrorMessageDisplay displayErrorAlertOnViewController:self withTitle:FB_LOGIN_CANCEL_TITLE andMessage:FB_LOGIN_CANCEL_MESSAGE];
[self.loginView enableLoginButtons];
} else {
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"me" parameters:nil] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id user, NSError *error) {
//TODO do something in here
}];
}
}];
Using the part of the code, the app still freeze on low memory after authenticated using facebook. In fact, the handler did not get call at all
Make sure you follow all the steps in https://developers.facebook.com/docs/ios/getting-started including connecting the application:didFinishLaunchingWithOptions: of the FBSDKApplicationDelegate (in addition to the openURL:)
Check FBSDKAccessToken currentAccessToken in an appropriate area of your app (such as viewDidLoad, as described in https://developers.facebook.com/docs/facebook-login/ios/). This will be set for you by the SDK in cases of a "cold start" of your app.

Trouble verifying Facebook publish_actions permission

I have successfully logged into Facebook and asked for publish_actions permission. The permission is granted, as I can readily verify on https://www.facebook.com/settings?tab=applications and also by calling
-(void) whatPermissionsDoIHave
{
[FBRequestConnection startWithGraphPath:#"/me/permissions"
completionHandler:^(
FBRequestConnection *connection,
NSDictionary* result,
NSError *error
) {
//do checks in here
}
}];
}
So I know for certain that I have permission. However, whenever it's time to share, my permission check returns false. I will now show my permission check
+ (BOOL)hasWritePermissions
{
if (!FBSession.activeSession.isOpen) return NO;
NSLog(#"So the session is at least open");
return [FBSession.activeSession.permissions indexOfObject:#[#"publish_actions"]] != NSNotFound;
}
So am I missing something else? Perhaps something I should have done in AppDelegate or such? Thanks for any insight.
Right now the only call I am making in AppDelegate is
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
fallbackHandler:^(FBAppCall *call) {
NSLog(#"In fallback handler");
}];
}
The permissions property is an array of strings, but you're calling indexOfObject on another array, which is probably why it can't find it. Try this instead:
return [FBSession.activeSession.permissions indexOfObject:#"publish_actions"] != NSNotFound;

ios Parse.com - After enabling the local datastore PFFacebookUtils loginWithPermission block is never called

After enabling the (new) local datastore in Parse version 1.6.1 for iOS the block in PFFacebookUtils loginWithPermission gets never called.
[Parse enableLocalDatastore];
[Parse setApplicationId:#"***" clientKey:#"***"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
// Gets never called
}];
When removing the [Parse enableLocalDatastore] the block gets called.
// [Parse enableLocalDatastore];
[Parse setApplicationId:#"***" clientKey:#"***"];
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
// Gets called as in previous versions
}];
I also have the app switching methods to support Facebook Single Sign-On in
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication withSession:[PFFacebookUtils session]];
}
I've checked the documentation and couldn't find any help. Did I miss something when enabling the local datastore?
The problem has been fixed in Parse 1.6.2
Maybe the local datastore is experiencing an exception.
Try to use
[[PFFacebookUtils loginWithPermissionsInBackground: perms] continueWithBlock: ^ id (BFTask * task) {
// breakpoint
}];
and inspect with lldb the task to see if task.exception is nil.
I'm having a similar problem: I can login to my app with the aforementioned method but then, if I logout, when I try lo log in again I am stuck and task.exception says:
Attempted to change an objectId to one that's already known to the
OfflineStore.
This could be related: https://developers.facebook.com/bugs/994229510592686/
It is a bug and it will be fixed in the next Parse SDK release.

Facebook ios sdk 3.5 openActiveSessionWithReadPermissions don't callback using web login

I just switched to Facebook ios sdk 3.5 and trying to authenticate user using
[FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:allowLoginUI completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
//callback methods
}];
I have setup the FacebookAppID, FacebookDisplayName, CFBundleURLSchemes in info.plist file.
And in AppDelegate, i have the following function setup:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [FBSession.activeSession handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL wasHandled = [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication];
// add app-specific handling code here
return wasHandled;
}
And now it is able to call the callback block when I'm having facebook account logged in on the iPhone itself, which I think it is used the new route for FBAppCall.
But the problem is when I don't setup my iPhone FB account, the app try to authenticate using safari web view or the FB app, then after the allow access button pressed on safari or the app, my App get called and it showed the Launch image, but it just hang there, and the callback block is never get called. I'm thinking this a different route for the application handling openurls, but I'm not sure since if i put a break point in the
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
It never get's stopped in the breakpoint.

Resources