fix(messaging): surface the APNs guidance for THIRD_PARTY_AUTH_ERROR - #3229
Open
milcho0604 wants to merge 1 commit into
Open
fix(messaging): surface the APNs guidance for THIRD_PARTY_AUTH_ERROR#3229milcho0604 wants to merge 1 commit into
milcho0604 wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request updates the error handling for THIRD_PARTY_AUTH_ERROR in the Firebase Messaging SDK. Instead of letting the generic server-side OAuth error message overwrite the SDK's specific guidance regarding APNs and web push credentials, the SDK now prepends its own descriptive message and appends the raw server response. Unit tests have been added to verify this behavior and ensure other error codes remain unaffected. I have no feedback to provide as there are no review comments.
milcho0604
force-pushed
the
fix/third-party-auth-error-message
branch
from
August 13, 2026 05:45
f2c6e89 to
216aa37
Compare
When FCM rejects a send with a provider-auth error, the accompanying server
message is often the generic gateway text ("Request is missing required
authentication credential. Expected OAuth 2 access token, login cookie or other
valid authentication credential."). fromServerError() lets any server message
replace the canonical one, so that text is what developers see. It describes the
caller's own credential, while the fault is an APNs or web push credential on
the project, so it sends people to audit their service account instead. The
SDK's own message for this code was unreachable in practice.
Lead with the canonical message for the server codes that name the provider
credential outright -- THIRD_PARTY_AUTH_ERROR, APNS_AUTH_ERROR and the legacy
InvalidApnsCredential -- and keep the server text after it.
UNAUTHENTICATED maps to the same client code but is deliberately excluded.
Without an FcmError detail it is the plain gateway rejection, which really can
mean this SDK's own credential is bad, so prefixing APNs guidance there would
point developers away from the actual fault. Keying on the server code rather
than the mapped client code keeps the two apart.
Also widen the canonical message, which named only an "APNs SSL certificate"
and development/production certificates. The backend documents this code as
"APNs certificate or web push auth key was invalid or missing", which also
covers APNs auth keys and Web Push.
test/unit/index.spec.ts did not import messaging-errors-internal.spec, so that
file never ran under `npm test`. Wired it in; the unit suite goes from 6064 to
6076 tests.
Fixes firebase#3215
milcho0604
force-pushed
the
fix/third-party-auth-error-message
branch
from
August 13, 2026 06:07
216aa37 to
5287915
Compare
milcho0604
marked this pull request as ready for review
August 13, 2026 06:11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3215.
The problem
When FCM rejects a send with a provider-auth error, the accompanying server message is often the generic gateway text:
FirebaseMessagingError.fromServerError()lets any server message replace the canonical one:so that text is what developers see. It describes the caller's own credential, while the actual fault is an APNs or web push credential on the Firebase project — so it sends people to audit their service account and OAuth setup, all of which are fine. The SDK already has a correct message for this code, but it was unreachable in practice, because the backend supplies a message.
The change
Server message: "...", so no detail is lost..p12model. The backend documents this code as "APNs certificate or web push auth key was invalid or missing", which also covers APNs auth keys and Web Push, and for those "certificate has expired" is itself misleading.messaging-errors-internal.specintotest/unit/index.spec.ts. It was not imported, so the file never ran undernpm test. The unit suite goes from 6064 to 6076 tests.Which server codes, and why not all of them
Four server codes map to
THIRD_PARTY_AUTH_ERROR, and they do not all mean the same thing:THIRD_PARTY_AUTH_ERRORAPNS_AUTH_ERRORInvalidApnsCredential(legacy)UNAUTHENTICATEDFcmErrordetail this is the plain gateway rejection, which can genuinely mean this SDK's own credential is badKeying the special case on the mapped client code would prepend APNs guidance to the last row too, which would be actively wrong when the caller's service account really is at fault. The condition therefore tests
serverErrorCode, which still tells them apart, and that path keeps showing the server message on its own.The canonical message likewise makes no claim about which credential is not at fault, because it is still the fallback for
UNAUTHENTICATEDwhen the backend sends no message at all.Tests
messaging-errors-internal.spec.tscovers, parameterized over the three provider-auth codes and varying the HTTP status so the behavior cannot be keyed on it:UNAUTHENTICATEDreturns the server message unchanged;NOT_FOUNDstill uses the server message verbatim, so the special case cannot silently widen.Each assertion was checked against a mutated source. Removing the
messageguard, looking the code up by the mapped client code, narrowing the set back to a single alias, coupling the branch to HTTP 401, and reducing the canonical message to a stub each make the relevant tests fail. The pre-existing cases inmessaging.spec.tsassertrejectedWith('test error message'), which is a substring match and passes either way, so they do not cover this.npm testpasses (6076 unit tests, lint clean) andnpm run api-extractorreports every API file up to date.Notes for reviewers
fromTopicManagementServerError()is deliberately untouched:TOPIC_MGT_SERVER_TO_CLIENT_CODEnever maps toTHIRD_PARTY_AUTH_ERROR.messagetext changes. If message text is treated as API surface, I am happy to narrow this to the condition change alone, or to reword.UNAUTHENTICATED → THIRD_PARTY_AUTH_ERRORmapping itself looks questionable, but changing it would changeerror.codefor existing callers, so it is left alone here.