facebook / facebook-ios-sdk

Used to integrate the Facebook Platform with your iOS & tvOS apps.
https://developers.facebook.com/docs/ios
Other
7.73k stars 3.5k forks source link

SDK v17.0.0 may not get valid AccessToken immediately after call ApplicationDelegate didFinishLaunchingWithOptions #2399

Open tzuyangliu opened 3 weeks ago

tzuyangliu commented 3 weeks ago

Checklist before submitting a bug report

Xcode version

15.2

Facebook iOS SDK version

17.0.0

Dependency Manager

CocoaPods

SDK Framework

Login

Goals

In response to Apple's privacy manifests requirements, upgrade Facebook SDK. Encounter this problem after upgrading.

Firstly, initializes the SDK when my app launch:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions{
  [[FBSDKApplicationDelegate sharedInstance] application:app didFinishLaunchingWithOptions:opitons];
  return YES;
}

Right after this, app will check for an existing token:

id token = [FBSDKAccessToken currentAccessToken];

Expected results

The [FBSDKAccessToken currentAccessToken] not be nil

Actual results

The [FBSDKAccessToken currentAccessToken] may be nil

I checked some previous stackoverflow question records(https://stackoverflow.com/questions/32950937/fbsdkaccesstoken-currentaccesstoken-nil-after-quitting-app) and found that it was not the same problem.

Steps to reproduce

I tried to compare the source code and found the reason for this difference.

Here's 17.0.0's FBSDKApplicationDelegate code:

  @discardableResult
  public func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    guard
      !isAppLaunched,
      !hasInitializeBeenCalled
    else { return false }

    initializeSDK(launchOptions: launchOptions) {
      self.isAppLaunched = true

      self.initializeTokenCache()
      self.fetchServerConfiguration()

      if self.components.settings.isAutoLogAppEventsEnabled {
        self.logSDKInitialize()
      }

      self.initializeProfile()
      self.checkAuthentication()
      _ = self.notifyLaunchObservers(application: application, launchOptions: launchOptions)
    }
    return true
  }

Here's 16.3.1's FBSDKApplicationDelegate code:

 @discardableResult
  public func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    guard
      !isAppLaunched,
      !hasInitializeBeenCalled
    else { return false }

    initializeSDK(launchOptions: launchOptions)
    isAppLaunched = true

    initializeTokenCache()
    fetchServerConfiguration()

    if components.settings.isAutoLogAppEventsEnabled {
      logSDKInitialize()
    }

    initializeProfile()
    checkAuthentication()

    return notifyLaunchObservers(application: application, launchOptions: launchOptions)
  }

Obviously, in the initialization logic of version 17.0.0, there is an additional asynchronous call, resulting in a scenario where the asynchronous logic is not completed after the initialization logic is completed. At this point, it becomes uncertain when the App can obtain the AccessToken. It seems that this asynchronous logic is to obtain a configuration called DomainConfiguration. This configuration may come from UserDefaults or may require a network request.

I also found a solution based on the source code, which is to wait for the FBSDKAccessTokenDidChangeNotification notification after startup, and then try to obtain the AccessToken. On the one hand, this will have an impact on the original business logic process, which is not reflected in the update document description; on the other hand, in the test scenario, I found that on some devices this time may exceed 10 seconds, which is unacceptable.

Code samples & details

No response

mikedJC commented 6 days ago

@tzuyangliu apple will allow using the previous sdk so you can save yourself the trouble of updating.

tzuyangliu commented 3 days ago

@tzuyangliu apple will allow using the previous sdk so you can save yourself the trouble of updating.

Thank you for providing the information : )