Skip to content

[firebase_auth]: iOS OAuthProvider('apple.com').credential sends empty access_token= param (nil→"" ObjC/Swift bridge) → "Invalid OAuth response from apple.com" #18445

Description

@gsdt

Is there an existing issue for this?

Which plugins are affected?

Auth

Which platforms are affected?

iOS

Description

On iOS, creating an Apple credential with the documented API:

final credential = OAuthProvider('apple.com').credential(
  idToken: identityToken,
  rawNonce: rawNonce,
);
await user.linkWithCredential(credential); // or signInWithCredential

always fails with:

[firebase_auth/invalid-credential] Invalid OAuth response from apple.com

even though the Apple identityToken is perfectly valid (correct aud, iss, matching nonce, valid signature — replaying the exact same token against accounts:signInWithIdp via plain REST succeeds).

Root cause

I captured the actual request the SDK sends by routing useAuthEmulator through a logging proxy that forwards to production. The verifyAssertion postBody the plugin produces is:

providerId=apple.com&id_token=<valid JWT>&nonce=<rawNonce>&access_token=

Note the trailing empty access_token= parameter. When access_token is present (even empty), the Identity Toolkit backend ignores the valid id_token and takes the access-token-exchange path with apple.com, which fails with INVALID_IDP_RESPONSE : Invalid OAuth response from apple.com.

Where the empty string comes from:

  1. Dart sends the credential map with accessToken: null (correct).
  2. FLTFirebaseAuthPlugin.mgetFIRAuthCredentialFromArguments takes the generic OAuth branch (signInMethod oauth) and calls:
    [FIROAuthProvider credentialWithProviderID:providerId
                                       IDToken:idToken
                                      rawNonce:rawNonce
                                   accessToken:accessToken]; // accessToken == nil
  3. In firebase-ios-sdk (12.15.0, Swift rewrite), that selector maps to OAuthProvider.swift:
    @objc(credentialWithProviderID:IDToken:rawNonce:accessToken:)
    public static func credential(withProviderID providerID: String, idToken: String,
                                  rawNonce: String,
                                  accessToken: String) -> OAuthCredential
    accessToken is declared non-optional String. Passing nil from Objective-C bridges it to an empty string instead of nil.
  4. VerifyAssertionRequest only skips access_token when it is nil"" is non-nil, so the empty parameter is appended to the postBody.

This is the same class of regression as #13242 / #3674 (optional parameter handling), resurfaced after the firebase-ios-sdk Swift rewrite.

Proof via REST (server error fingerprint)

Same fake-signature token, only difference is the empty parameter:

postBody server response
providerId=apple.com&id_token=<t>&nonce=<n> INVALID_IDP_RESPONSE : Unable to verify the ID Token signature. (proceeds to signature check → a real token succeeds)
providerId=apple.com&id_token=<t>&nonce=<n>&access_token= INVALID_IDP_RESPONSE : Invalid OAuth response from apple.com

Workarounds

Suggested fix

In getFIRAuthCredentialFromArguments (generic OAuth branch), when accessToken == nil call the credentialWithProviderID:IDToken:rawNonce: selector instead of passing nil into the non-optional 4-arg variant (and similarly audit other optional params passed into the Swift-rewritten SDK). Alternatively fix the optionality upstream in firebase-ios-sdk.

Reproducing the issue

  1. iOS app, firebase_auth: 6.5.4 (firebase-ios-sdk 12.15.0 via SPM).
  2. Sign in with Apple natively (e.g. sign_in_with_apple), obtain identityToken + rawNonce.
  3. OAuthProvider('apple.com').credential(idToken: ..., rawNonce: ...)signInWithCredential or linkWithCredential.
  4. Observe [firebase_auth/invalid-credential] Invalid OAuth response from apple.com.

No dashboard configuration issue is involved: Apple provider enabled (native-only, empty Services ID config), bundle ID registered, token aud/nonce verified correct.

Firebase Core version

4.11.0

Flutter Version

3.35 (Dart SDK ^3.12.2)

Relevant Log Output

flutter: [firebase_auth/invalid-credential] Invalid OAuth response from apple.com

Captured verifyAssertion request body (via logging proxy):
{
  "returnSecureToken" : true,
  "returnIdpCredential" : true,
  "postBody" : "providerId=apple.com&id_token=<REDACTED valid Apple JWT>&nonce=<rawNonce>&access_token=",
  "idToken" : "<anonymous user idToken>",
  "requestUri" : "http://localhost",
  "autoCreate" : true
}
Response:
{ "error": { "code": 400, "message": "INVALID_IDP_RESPONSE : Invalid OAuth response from apple.com" } }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs AttentionThis issue needs maintainer attention.platform: iosIssues / PRs which are specifically for iOS.plugin: authtype: bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions