Short answer
For each sign-in, generate one random nonce. Pass its SHA256 hash, as a hex string, to the Apple request, and pass the raw nonce as rawNonce when you create the Firebase credential. On Flutter, signInWithProvider with AppleAuthProvider handles the nonce for you.
Rather not fix it yourself? App Fix Ticket starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.
Why Firebase rejects the nonce, and the fix
01
The hashed nonce went to Firebase
“You will send the SHA256 hash of the nonce with your sign-in request, which Apple will pass unchanged in the response.” Firebase, Sign in with Apple (iOS)
The most common mix-up: the app passes the hash to both sides. Apple gets the hash; Firebase gets the original string.
final rawNonce = generateNonce(); // your own helper: a random string per sign-in final hashed = sha256.convert(utf8.encode(rawNonce)).toString(); final apple = await SignInWithApple.getAppleIDCredential( scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName], nonce: hashed, ); final credential = OAuthProvider('apple.com').credential( idToken: apple.identityToken, rawNonce: rawNonce, ); await FirebaseAuth.instance.signInWithCredential(credential);02
No nonce was sent to Apple
“Firebase validates the response by hashing the original nonce and comparing it to the value passed by Apple.” Firebase, Sign in with Apple (iOS)
Without a nonce in the Apple request, the ID token has nothing for Firebase to compare. Always set the nonce on the Apple request.
03
The nonce changed between request and sign-in
Generating a new nonce after the Apple sheet opens, or keeping it in a widget that rebuilt, breaks the match. Keep the raw nonce from that attempt until signInWithCredential finishes.
04
The hash is not a hex string
Also check: Firebase’s sample asks for the SHA256 hash as a hex string. Base64 or raw bytes won’t match what Firebase computes.
Checked against the vendor’s docs on : Firebase docs: Sign in with Apple (Apple platforms).
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Very responsive, attentive to fixing bugs, and completed the project as needed! Thank you!”
Related: Firebase auth/credential-already-in-use · Firebase auth/operation-not-allowed · Firebase account-exists-with-different-credential · Firebase missing initial state