Fbsession.Activesession.Isopen Returns No Even Though the User Logged-In

FBSession.activeSession.isOpen returns NO even though the user logged-in

It's just a facebook behavior, you need to 'reopen' the session everytime you launch the app, your guess is sort of right, It's because of the token state, a simple solution is that you check the [FBSession activeSession].isOpen state and if it returns NO call the openActiveSessionWithAllowLoginUI << Yes the same facebook method, but checking all the states it returns.

If the session was previously opened then it uses the stored token to reopen the session, you shouldn't worry about the login UI because it won't show up again as the session was previously opened.

if (![FBSession activeSession].isOpen) {
[self connectWithFacebook];
}

- (void) connectWithFacebook {
// The user has initiated a login, so call the openSession method
// and show the login UI if necessary << Only if user has never
// logged in or ir requesting new permissions.
PPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:YES];
}

And in the app delegate

- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
NSArray *permissions = @[@"any_READ_permision_you_may_need"];

return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if (error) {
NSLog (@"Handle error %@", error.localizedDescription);
} else {
[self checkSessionState:state];
}
}];
}

- (void) checkSessionState:(FBState)state {
switch (state) {
case FBSessionStateOpen:
break;
case FBSessionStateCreated:
break;
case FBSessionStateCreatedOpening:
break;
case FBSessionStateCreatedTokenLoaded:
break;
case FBSessionStateOpenTokenExtended:
// I think this is the state that is calling
break;
case FBSessionStateClosed:
break;
case FBSessionStateClosedLoginFailed:
break;
default:
break;
}
}

It's a quick fix and it works, you can reproduce it also just by closing the session but without clearing the token cache using [[FBSession activeSession] close] You can even change the token cache policy as described here http://developers.facebook.com/docs/howtos/token-caching-ios-sdk/

Handle invalid accessToken with FBSession openActiveSessionWithReadPermissions in Facebook iOS 3.1.1 SDK

The questions you linked are relevant, especially Facebook SDK 3.1 - Error validating access token which explains the problem where the Facebook account on the device is out of sync with the server (I.e., if you deleted the app from App Center). As mentioned there, in 3.1.1 the SDK will call to renew the device token only when it gets the invalid response from the server. This is a trade off in convenience for less round-trips to the server.

Assuming your code block is executed on applicationDidFinishLaunching or something similar, it will go to the else block because the app starts with a new session. When it calls openActiveSessionWithReadPermissions, the iOS 6 device thinks the token is valid and will let the state go to Open, so then your "do something" gets executed. Only then does the SDK get the invalid response from the server and invalidate the device token. As a result, the next time the procedure is called, it will prompt the user appropriately to authorize again.

This is intentional. For now, you can consider a automatic retry in your application if the error code describes an invalid token. For example, see the Scrumptious sample postOpenGraph retry code. In your case, it may look closer to something like (I used requestForMe as the "do something" for demonstration purposes):

else {
[FBSessionopenActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if(FB_ISSESSIONOPENWITHSTATE(status)) {
//do something
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error){
NSLog(@"success on first try");
} else if ([[error userInfo][FBErrorParsedJSONResponseKey][@"body"][@"error"][@"code"] compare:@190] == NSOrderedSame) {
//requestForMe failed due to error validating access token (code 190), so retry login
[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error){
//do something again, or consider recursive call with a max retry count.
NSLog(@"success on retry");
}
}];
}
}];
}
}];
}

Opening FBSession in consecutive launches (FB SDK for SDK 3.0)

I'm including a Facebook utility class I wrote that helps with understanding login state, because I expose a "logged in" / "not logged in" message to the user in my own Settings UI, in addition to using the actual 'FBLoginView' component when it comes time to allow the user to toggle authorization state.

The code below is also available via this gist.

I may not have interpreted all the FBSessionState types correctly in my switch statement, but thus far, it's served me well in the cases I've tested (I've just put this together).

The key thing to note, that others have alluded to, is that sometimes you have a cached authorization token that you can't use immediately, but if you make a Facebook open call on it, you can get it to be reusable (refreshed). This open call works behind the scenes, without triggering any UI / jarring OAuth window/app switching (if you have a cached token).

See my comments in the method isLoggedInAfterOpenAttempt. Note how I check for the state to be FBSessionStateCreatedTokenLoaded and only then, make the call to

-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error).

Other tidbits about this class:

  • I have a property here to cache the logged in user, of type conforming to protocol FBGraphUser. It's not used in any of the login methods demonstrated here, though.
  • The Facebook SDK 3.0 for iOS sample code suggests constructing your own class to hold on to and manage these kinds of operations, if you have anything more than a trivial app. This class of mine below is the beginnings of that idea for my app.
  • You can replace my 'log4Info' and 'log4Debug' macros with NSLog to get this working.

#import "UWFacebookService.h"

@implementation UWFacebookService

// Static
static const int ddLogLevel = LOG_LEVEL_DEBUG;

// Strong
@synthesize facebookGraphUser = _facebookGraphUser;

#pragma mark - Inquiries

- (BOOL)isSessionStateEffectivelyLoggedIn:(FBSessionState)state {
BOOL effectivelyLoggedIn;

switch (state) {
case FBSessionStateOpen:
log4Info(@"Facebook session state: FBSessionStateOpen");
effectivelyLoggedIn = YES;
break;
case FBSessionStateCreatedTokenLoaded:
log4Info(@"Facebook session state: FBSessionStateCreatedTokenLoaded");
effectivelyLoggedIn = YES;
break;
case FBSessionStateOpenTokenExtended:
log4Info(@"Facebook session state: FBSessionStateOpenTokenExtended");
effectivelyLoggedIn = YES;
break;
default:
log4Info(@"Facebook session state: not of one of the open or openable types.");
effectivelyLoggedIn = NO;
break;
}

return effectivelyLoggedIn;
}

/**
* Determines if the Facebook session has an authorized state. It might still need to be opened if it is a cached
* token, but the purpose of this call is to determine if the user is authorized at least that they will not be
* explicitly asked anything.
*/
- (BOOL)isLoggedIn {
FBSession *activeSession = [FBSession activeSession];
FBSessionState state = activeSession.state;
BOOL isLoggedIn = activeSession && [self isSessionStateEffectivelyLoggedIn:state];

log4Info(@"Facebook active session state: %d; logged in conclusion: %@", state, (isLoggedIn ? @"YES" : @"NO"));

return isLoggedIn;
}

/**
* Attempts to silently open the Facebook session if we have a valid token loaded (that perhaps needs a behind the scenes refresh).
* After that attempt, we defer to the basic concept of the session being in one of the valid authorized states.
*/
- (BOOL)isLoggedInAfterOpenAttempt {
log4Debug(@"FBSession.activeSession: %@", FBSession.activeSession);

// If we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button over in Settings, and so
// we check here to make sure we have a token before calling open
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
log4Info(@"We have a cached token, so we're going to re-establish the login for the user.");
// Even though we had a cached token, we need to login to make the session usable:
[FBSession.activeSession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
log4Info(@"Finished opening login session, with state: %d", status);
}];
}
else {
log4Info(@"Active session wasn't in state 'FBSessionStateCreatedTokenLoaded'. It has state: %d", FBSession.activeSession.state);
}

return [self isLoggedIn];
}

@end

Cannot send facebook apprequest from iOS because FBSession.activeSession.isOpen gives false

You say "FBSession.activeSession.isOpen gives false", but, just to be sure : when do you run this test? When your call to the login request returns, or inside the asynchronous request's callback ?

If it's done outside the request's callback, it may say that the session is not opened yet. Then, the request returns properly, which means that any further call to another FB request succeeds.

Does that help?

If it does not, maybe an overview of your code could.

Facebook iOS SDK 3.1.1 closeAndClearTokenInformation method no working

Maybe this will help.
https://developers.facebook.com/bugs/497294866962479?browse=search_507cb8ebc4f025673237228

I call all these methods together to make sure it is really logout. Crazy bugs.

[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession setActiveSession:nil];

Facebook iOS seems lost session when return to app after clicking Okay to You have already authorized app

I found the problem. In the plist, "Application does not run in background" was set to YES. Setting to NO solved the problem.

Facebook iOS SDK v4.0 Check User Session State

There are some changes on v4.0. You can check all of them here: https://developers.facebook.com/docs/ios/upgrading-4.x

In order to check user's session, now you should use [FBSDKAccessToken currentAccessToken].

FBSession.activeSession has been replaced with [FBSDKAccessToken currentAccessToken] and FBSDKLoginManager. There is no concept of session state. Instead, use the manager to login and this sets the currentAccessToken reference.



Related Topics



Leave a reply



Submit