facebook repeatedly prompts for permissions - ios

every time you tap the facebook login button you are asked to accept the read permissions regardless of whether you just accepted them on your previous login attempt. you can accept the read permissions and land back in the app, only to logout, login, and be presented with the read permissions to accept yet again.
this issue did not exist prior to 3.5, 3.5.1, or the new 3.5.2. Due to this issue my application is stuck on the latest version of the pre v3.5 version of the sdk (3.2.1).
to me, this sounds like a bug in the facebook sdk/app but when i submitted this bug report it was marked as "triaged/low priority" and had the following note attached: "Thanks for the report. We are prioritizing other reports at the moment. You may want to check out http://facebook.stackoverflow.com/" so here i am.
my logic behind the assertion of it being a facebook server side thing is that we are making an auth request to facebook. it is within the facebook realm that they decide what permissions you have and have not accepted. how can it be a fault on my side? it is not the developer's job to tell facebook what their own user has accepted or not.
heres the code that i have behind the "Login with Facebook" button touch up event:
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
if (appDelegate.session.state != FBSessionStateCreated) {
appDelegate.session = [[FBSession alloc] initWithPermissions:permissions];
}
[appDelegate.session openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if([appDelegate.session isOpen]) {
//login ui flow finished here
}
}];
anybody have any thoughts?

Related

iOS Facebook SDK Login View sometimes shows Desktop Web rather than Mobile Web

I'm using the latest FB SDK via Pods - version 3.18.2, with Xcode 5 in and iPhone only app. I use the FBLoginView in the Storyboard, so tapping it pops open the Facebook login for the app, and login actions call the delegate of the parent View controller of that FBLoginView button.
It all works fine -- but, sometimes the Desktop version of the login shows up rather than the Mobile version. It's intermittent -- I have tester where it never shows, one who gets it sometimes, and one who gets it often.
Any idea how I can prevent the SDK from showing the Desktop login?
If the user doesn't have the Facebook native app installed the facebook website will open.
Otherwise it will open the Facebook native app.
There is a function called openWithBehavior in the Facebook SDK that works on sessions. Use that like I have shown below:
FBSession *session = [[FBSession alloc] initWithPermissions:#[#"public_profile", #"email",#"user_location",#"user_birthday",#"user_likes"]];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorForcingWebView
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (FBSession.activeSession.isOpen) {
//Do Something
}
}
]

my app is not switching to facebook ios native app on opening a fbsession

I am using xcode 5.1.1, ios 7.1.1, cocos2d 2.1, facebook ios sdk 3.14 on mac OSX Maverics 10.9.2.
I have defined a FBSession property in appDelegate. And in another CCMenuItemImage click event I have
if (appDelegate.session.isOpen) {
[appDelegate.session closeAndClearTokenInformation];
} else
{
if (appDelegate.session.state != FBSessionStateCreated) {
// Create a new, logged out session.
appDelegate.session = [[FBSession alloc] init];
}
appDelegate.session = [[[FBSession alloc] initWithPermissions:permissions] autorelease];
// if the session isn't open, let's open it now and present the login UX to the user
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
NSLog(#"IT NEVER PRINTS %#",session.accessTokenData.accessToken);
}];
}
And in appDelegate.m I have:
- (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
withSession:self.session];
}
When i run the sample facebook code it launches the facebook ios native app to login/ask for permission. And when I run this above code it does nothing. I tried with and without signing into facebook ios app and settings->general-facebook. In developer.facebook.com app setting I have SSO enabled. Please help.
EDIT:
I am getting random issues like:
1> the error: "FBSDKLog: Cannot use the Facebook app or Safari to authorize, fb**** is not registered as a URL Scheme".
2> getting the access token without a valid FBSession.
3> Sometime the webpage login windows popped with the #1 error mentioned above.
4> And some time the above error#3 pops and goes off with log printing user canceled.
Issue just resolved by deleting the test app and it's associated test users that i created in the "developer.facebook.com->app" page under "Test Apps". This is weird but resolved all my problems.
Though my above code works fine but I found "Build Your Own Button" part in https://developers.facebook.com/docs/facebook-login/ios/v2.0#login-apicalls is useful and I modified my code according to this link.
In this same link I also noticed which I was not aware of:
"When someone connects with an app using Facebook login, the app can access their public profile and friend list, the pieces of information that are visible to everyone. To create this basic connection, apps must always request access to a person's public profile information by asking for the public_profile permission."
Hope this will help someone else!!!
I had this same issue recently. I was able to fix it by upgrading from version 4.6.0 of FBSDKCoreKit to version 4.7.0.
Facebook strongly recommends using the FBSDK libs over the old Facebook-iOS-SDK, so switching is a good idea.
Also, make sure you set the proper LSApplicationQueriesSchemes if you're on iOS 9
Facebook has some info on iOS 9 integration here: https://developers.facebook.com/docs/ios/ios9

How to request for Facebook XMPP chat permission in iOS?

My app needs to send a private message to the user's Facebook friend. The user needs to grant the XMPP permission before my app can do this.
[[FBSession activeSession]
requestNewPublishPermissions:[NSArray arrayWithObjects:
#"publish_stream",
#"xmpp_login",
nil
]
defaultAudience:FBSessionDefaultAudienceEveryone
completionHandler:^(FBSession *session, NSError *error) {
}
];
The above code will pop up this alert view as expected:
However, even before tapping any button, this warning is printed out in the debug log:
FBSDKLog: FBSession: a permission request for publish or manage
permissions contains unexpected read permissions
Surely enough, after tapping the "OK" button, the completion handler comes back with an error, containing the same warning. I understand that the Facebook API requires asking for read and write permissions separately, but the xmpp_login permission seems to need both read and write at the same time. I'm at a dead end here.
iOS 7.1
Facebook SDK 3.12.0
Xcode 5.1
See the section Extended Permissions in this link.
According to this, xmpp_login is the read permission, not the write/publish permission. So you should add that the readPermission

How is FBSession used

I'm integrating facebook and I still don't see how the FBSession ties everything together.
This is how I think it works.
You need a new FBSession each app launch. (Is this true?). The FBSession also needs to be closed every time the app stops (if this is true, how do we start a new session without asking user to login again?)
As far as the session is concerned, [FBSession activeSession] is a global managed by the facebook sdk? Should we just use this as the default session anytime we want to pull data or check if a session is alive?
Assuming the above logic has worked out and you get the user id (fb id) then we feed that id to a FBImageView and we get a profile pic, but isn't this id changing every launch? So storing it on our server isn't helpful? Should we get the id every launch?
Please let me know what is right or wrong about the above statements, and an explanation of why?
Thank you.
I suggest you to use activeSession of FBSession. This way you don't have to create sessions yourself. Just use [FBSession openActiveSessionWithReadPermissions:...] method of FBSession for activating activeSession, and on successful opening, You could use FBSession.activeSession for your Facebook requests. Good luck!
PS>
In order to restore activeSession you can do:
if (![FBSession.activeSession isOpen]) {
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info"] allowLoginUI:NO completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
}];
}
which will open the session if it has cached token information without showing login UI.

FBSession requestNewPublishPermissions fails before response

I'm trying to get post permissions from a user using the Facebook SDK on iOS.
I'm calling the code below in a method that is called if the app does not have the required publishing permissions to post to the users facebook wall.
// No permissions found in session, ask for it
[FBSession.activeSession requestNewPublishPermissions: [NSArray arrayWithObject:#"publish_actions"]
defaultAudience: FBSessionDefaultAudienceEveryone
completionHandler: ^(FBSession *session, NSError *error)
{
if( !error )
{
// Do something
}
}];
The first time I call this code it takes the user to the permissions page, and before it even switches to safari on the device the block gets called and this error message is returned
Error Domain=com.facebook.sdk Code=2 "The operation couldn’t be completed. (com.facebook.sdk error 2.)" UserInfo=0xc426410 {com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:ErrorReauthorizeFailedReasonUserCancelled,
The app then continues on to show the permissions page in safari where the user selects ok. Then it returns to the app. Permissions have not been set at this point even tho the user was presented with the permissions page and accepted.
When trying to post a second time it takes the user to the permissions page in safari and the requestNewPublishPermissions method doesn't fail instantly. The user selects ok and then everything works as expected.
So it is only on the very first time calling requestNewPublishPermissions that it fails instantly returning the error ErrorReauthorizeFailedReasonUserCancelled.
This happens in the simulator and on the device.
Any idea what might be causing this?
I found the solution to this problem on the answer to this question Facebook iOS 3.1 sdk login with publish permission callbacks
dispatch_async(dispatch_get_current_queue(), ^{
[self openSessionForPublishPermissions];
});
Where opensessionforpublishpermissions is the method that contains the requestNewPublishPermissions method.
"The reason is that the call to reauthorize.. needs to be after the event loop of which openActiveSession.. is called."
I assume this is a bug in the Facebook SDK, it doesn't make sense for this to be normal behaviour and I haven't seen any of the Facebook docs comment on this being the expected behaviour.
I had the similar issue, and the answer, provided by Tiddly worked for me. For some time.
Later I ran across the same issue. I don't know why, may be it was concerned with SDK or iOS updates, may be run loop of the app became more complicated. So I inspected FB SDK source and figured out that this issue occurs when you ask publish permissions just after read permissions, like this:
// Open with read permissions
[FBSession openActiveSessionWithReadPermissions: readPermissions
allowLoginUI: YES
completionHandler: ^
(FBSession *session, FBSessionState status, NSError *error)
{
// Ask for publish permissions (This is incorrect!)
[FBSession.activeSession requestNewPublishPermissions:publishPermissions
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:
^(FBSession *session, NSError *error)
{
// ...
}];
}];
When your app switches to Safari or FacebookApp and back,
-application: openURL: sourceApplication: annotation:
is called. CompletionHandler of
+openActiveSessionWithReadPermissions:
called immediately after this, before
applicationDidBecomeActive:. And after you start reauthorisation
applicationDidBecomeActive: is finally called. So, FB SDK think that user has returned back to the app, without giving permissions and reauthorisation fails with that "com.facebook.sdk error 2." error.
Sometimes dispatch_async() works well. But the robust solution, is to wait for active session to handle App Did Become Active event. And then request additional publish permissions. Here is an example of how to achieve this:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBAppCall handleDidBecomeActive];
if (self.shouldReauthorise) {
[self requestPublishPermissions];
self.shouldReauthorise = NO;
}
}

Resources