Skip to content

Crash in FUIAuth when custom FUIAuthProvider uses signInWithCustomToken (Resulting Credential is nil) #1322

@fangyuxi

Description

@fangyuxi

Step 1: Describe the issue

I am implementing a custom FUIAuthProvider to support a third-party login (e.g., Line Login) that integrates via a custom backend flow. The authentication process involves:

  1. Getting an access token from the third-party SDK.
  2. Exchanging it for a Firebase Custom Token via my backend.
  3. Signing in using [[FIRAuth auth] signInWithCustomToken:...].

The Issue:
According to the Firebase SDK documentation, signInWithCustomToken successfully signs the user in but returns a FIRAuthDataResult where the credential property is nil. This is expected behavior for custom tokens as they don't generate an OAuth credential.

However, when I pass this nil credential to the FUIAuthProviderSignInCompletionBlock (to signal a successful login), FirebaseUI crashes internally.

It appears that FUIAuth or VerifyAssertionRequest assumes that a successful login (non-nil error) must be accompanied by a non-nil FIRAuthCredential object. It attempts to access properties on this nil object (likely provider), resulting in a Bad Access crash.

Step 2: Steps to reproduce

  1. Create a class that conforms to FUIAuthProvider.
  2. Implement signInWithDefaultValue:presentingViewController:completion:.
  3. Inside the implementation, perform a sign-in using [[FIRAuth auth] signInWithCustomToken:token completion:...].
  4. In the completion handler, observe that authResult.credential is nil.
  5. Call the FirebaseUI completion block with this nil credential:
    // authResult.credential is nil here
    completion(authResult.credential, nil, nil, nil);
  6. The app crashes immediately.

Code Sample

// Inside a custom FUIAuthProvider implementation
- (void)signInWithDefaultValue:(nullable NSString *)defaultValue
      presentingViewController:(nullable UIViewController *)presentingViewController
                    completion:(nullable FUIAuthProviderSignInCompletionBlock)completion {

    // ... logic to get custom token ...

    [[FIRAuth auth] signInWithCustomToken:customToken completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
        if (error) {
            completion(nil, error, nil, nil);
            return;
        }

        // authResult.credential is NIL for custom tokens (Design behavior of the main SDK).
        // Passing this nil credential causes FUIAuth to crash.
        completion(authResult.credential, nil, nil, nil);
    }];
}

Step 3: Expected behavior

FirebaseUI should gracefully handle the case where a custom provider signs in successfully via a Custom Token (where no OAuth credential exists).

Since signInWithCustomToken is a valid way to authenticate, FUIAuth should check if [FIRAuth auth].currentUser is set, or allow a nil credential in the completion block without crashing, and proceed to the authUI:didSignInWith:error: delegate method.

Step 4: Actual behavior

The app crashes with EXC_BAD_ACCESS.

Crash Log snippet:

Task 55: EXC_BAD_ACCESS (code=1, address=0x8)
...
[VerifyAssertionRequest ...] 
...

(It seems to be trying to access a property, likely provider, on the nil credential object).

Step 5: Environment details

  • Xcode version: [26]
  • FirebaseSDK version: [last version]
  • FirebaseUI version: [15.1.0],
  • Installation method: CocoaPods

Workaround

To prevent the crash, I currently have to "trick" FirebaseUI by reporting a fake "User Cancelled" error when the custom token login succeeds. This stops FirebaseUI from processing the nil credential, and I manually handle the successful state in the FUIAuthDelegate.

// Current workaround
if (authResult.credential == nil) {
    // Manually dismiss the view controller on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
    });

    // Send a fake cancel error to stop FUIAuth internal processing
    NSError *cancelError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil];
    completion(nil, cancelError, nil, nil);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions