`FBSDKAuthenticationToken.current` returns the actual valid authentication token only after a certain delay
GalBerezansky opened this issue · comments
Checklist before submitting a bug report
- I've updated to the latest released version of the SDK
- I've searched for existing GitHub issues
- I've looked for existing answers on Stack Overflow, the Facebook Developer Community Forum and the Facebook Developers Group
- I've read the Code of Conduct
- This issue is not security related and can safely be disclosed publicly on GitHub
Xcode version
15.2
Facebook iOS SDK version
17.0.1
Dependency Manager
Prebuilt Binaries
SDK Framework
Login
Goals
I want to use FBSDKAuthenticationToken.currentAuthenticationToken
when the user opens the application, this user has logged-in with the limited log-in in a previous session and I'd like to use his authentication token.
Expected results
To get a non-nil FBSDKAuthenticationToken.currentAuthenticationToken
whenever it is called, it happens after the set-up of the facebook-ios-sdk, the facebook-ios-sdk should be useable at that time.
Actual results
In reality FBSDKAuthenticationToken.currentAuthenticationToken
is nil
when I first access it, I get the non-nil valid value only with a retry mechanism. With solid internet connection I get the non-nil auth token only after 0.4 seconds after the first call to the the method approximately.
The main issue is I don't know when the user is actually logged-out and when the authentication token in nil
because of this delay, if the user logs-out via facebook's side I'll just run my retry mechanism until I reach time out.
It is worth noting that the exact same issue occurs with FBSDKAccessToken.currentAccessToken
in the non-limited regular log-in. When I used version 12.3.1 of the sdk I got the valid non-nil value as soon as I accessed it, now I get the same delay there.
The currentAuthenticationToken
isn't well documented, it isn't clear when it should be nil
or not, it feels like there was a behavior change under the hood.
Bottom line, please explain when and why the authentication token is nil
, when should I decide that the user is actually logged-out and when I need to wait/retry, an even better solution is to ensure that the FBSDKAuthenticationToken.currentAuthenticationToken
and FBSDKAccessToken.currentAccessToken
are accessible as soon as possible whenever they have a value, otherwise doc them to explain how they should be used.
Thanks!
Steps to reproduce
- Successfully log-in with the limited facebook log-in.
- Close the application.
- Re-open it, the first access to
FBSDKAuthenticationToken.currentAuthenticationToken
isnil
even though the user should be logged-in.
Code samples & details
// The code the does the facebook log-in
- (void)loginWithPresentingViewController:(UIViewController *)presentingViewController
block:(void(^)(NSString * _Nullable token, BOOL cancelled,
NSError * _Nullable error))block {
auto configuration =
[[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"]
tracking:FBSDKLoginTrackingLimited];
dispatch_async(dispatch_get_main_queue(), ^{
[self.loginManager logInFromViewController:presentingViewController
configuration:configuration
completion:^(FBSDKLoginManagerLoginResult * _Nullable result,
NSError * _Nullable error) {
if (!result || result.isCancelled) {
block(nil, result.isCancelled ?: NO, error);
return;
}
if (![self.loginPermissions isSubsetOfSet:nn(result.grantedPermissions)]) {
block(nil, NO, [NSError lt_errorWithCode:FORErrorCodeLoginFailed description:@"An error occured");
return;
}
block(nn(result.authenticationToken.tokenString), NO, nil);
}];
});
}
// The code that returns a `nil` authentication token.
- (void)loginStatusWithBlock:(void(^)(FORLoginSourceLoginStatus *tokenStatus,
NSString * _Nullable token, NSError * _Nullable error))block {
auto _Nullable currentAuthenticationToken = FBSDKAuthenticationToken.currentAuthenticationToken; // Here I get `nil` even though the user has successfully logged-in in the previous session.
if (currentAuthenticationToken) {
auto loginStatus = currentAuthenticationToken.lt_isActive ?
$(FORLoginSourceLoginStatusLoggedIn) : $(FORLoginSourceLoginStatusLoginExpired);
block(loginStatus, nn(currentAuthenticationToken.tokenString), nil);
} else {
block($(FORLoginSourceLoginStatusNotLoggedIn), nil, nil);
}
}
// The code that enables getting the non-nil authentication token with the retry mechanism.
- (void)loginStatusWithBlock:(void(^)(FORLoginSourceLoginStatus *tokenStatus,
NSString * _Nullable token, NSError * _Nullable error))block {
__block uint attempt = 0;
dispatch_queue_t queue = dispatch_queue_create("some queue", DISPATCH_QUEUE_SERIAL);
__block void (^retryRetrieveFacebookAccessTokenBlock)(void) = [^{
/// Works only after a few retries, approximately 4 retries in my case.
auto _Nullable currentAuthenticationToken = FBSDKAuthenticationToken.currentAuthenticationToken;
if (currentAuthenticationToken) {
/// Here I parse the JWT token to check if the token is expired or not.
auto loginStatus = currentAuthenticationToken.lt_isActive ?
$(FORLoginSourceLoginStatusLoggedIn) : $(FORLoginSourceLoginStatusLoginExpired);
block(loginStatus, nn(currentAuthenticationToken.tokenString), nil);
} else if (attempt < FORFacebookLoginSource.kMaxRetrieveFacebookAccessTokenRetryCount) {
++attempt;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC));
dispatch_after(delay, queue, retryRetrieveFacebookAccessTokenBlock);
} else {
block($(FORLoginSourceLoginStatusNotLoggedIn), nil, nil);
return;
}
} copy];
retryRetrieveFacebookAccessTokenBlock();
}
+ (uint)kMaxRetrieveFacebookAccessTokenRetryCount {
return 20;
}
Same issue