Your push send fails with 403 SENDER_ID_MISMATCH, or the Node.js Admin SDK throws messaging/mismatched-credential. The token isn't dead. Your server is sending from a different Firebase project than the one the app registered with.
What the error looks like
The FCM HTTP v1 API returns a 403 with the error code in the details:
{
"error": {
"code": 403,
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.firebase.fcm.v1.FcmError",
"errorCode": "SENDER_ID_MISMATCH"
}
]
}
}Firebase's description: the authenticated sender ID is different from the sender ID for the registration token. A token is tied to the senders of the project the app used when it registered, and only those senders can use it.
Common causes
- Dev and production projects are mixed up. The app was built with the dev
google-services.jsonorGoogleService-Info.plist, while the server uses the production service account, or the other way round. Build flavors and schemes make this easy to miss. - You moved to a new Firebase project. Old installs still hold tokens from the old project.
- The server uses the wrong key file. A service account key from another project, or a project ID in the send URL that doesn't match the key.
- Several apps share one server. Tokens from apps in different projects are stored together and sent with one set of credentials.
How to find the mismatch
Compare the project the app uses with the project the server uses:
# Android app: the sender ID is the project number
google-services.json -> project_info.project_number
project_info.project_id
# iOS app
GoogleService-Info.plist -> GCM_SENDER_ID
PROJECT_ID
# Your server: the project in the service account key and the send URL
service-account.json -> project_id
POST https://fcm.googleapis.com/v1/projects/<project_id>/messages:send- Open the config file that is actually bundled in the build that produced the token.
- Note its project ID and sender ID (on Android the sender ID is the
project_number). - Check the
project_idin the server's service account key and in the send URL. - They must all point to the same Firebase project.
A quick test: install a fresh build on a test phone, copy its token, and send to it from the project in that build's config file. If that works, the setup is fine and the failing tokens belong to another project.
How to fix it
- Send with the matching project. Use the service account and project ID that match the app's config file.
- Store the project with each token. If you run several apps or environments, save which project a token came from and choose credentials per send.
- After a project move, let tokens refresh. Ship the build with the new config, upload the new token on app start, and keep sending to old tokens from the old project until users update.
- Don't bulk-delete tokens on this error. Firebase's clean-up advice is for UNREGISTERED and, when the payload is valid,
INVALID_ARGUMENT. Deleting on a mismatch can wipe tokens that work fine with the right project.
You can build a valid test message with the free FCM payload builder, so the payload isn't in question while you test.
Related errors
UNREGISTERED(404): the token is no longer valid. Delete it. See FCM UNREGISTERED: Requested entity was not found.THIRD_PARTY_AUTH_ERROR(401): the APNs key or certificate in Firebase is missing or invalid.- On iOS, if you send to APNs directly, a token sent to the wrong environment returns BadDeviceToken.
On notifySphere
notifySphere sends through FCM with the Firebase credentials you add for each app, so each app's devices are sent with that app's project. The React Native and Flutter SDKs register the device for you.
Frequently asked questions
What does FCM SENDER_ID_MISMATCH mean?
Firebase describes it as: the authenticated sender ID is different from the sender ID for the registration token. In practice, the token was created by an app connected to one Firebase project, and your server is sending with credentials from another project.
Is messaging/mismatched-credential the same error?
Yes. The Firebase Admin SDK for Node.js reports SENDER_ID_MISMATCH as messaging/mismatched-credential, with a message saying the credential doesn't have permission to send to that token.
Should I delete tokens that return SENDER_ID_MISMATCH?
Not as a first step. Firebase's token clean-up advice covers UNREGISTERED and, with a valid payload, INVALID_ARGUMENT. A mismatch usually means your server is using the wrong project, so the tokens may be fine for the right one. Fix the credentials, then retry.
Why did SENDER_ID_MISMATCH start after I moved to a new Firebase project?
Tokens are tied to the project the app registered with. Existing installs keep their old tokens until they run a build connected to the new project and register again. Until then, sending to those tokens from the new project fails with SENDER_ID_MISMATCH.
Can one server send to apps in two Firebase projects?
Yes, but each send must use credentials and a project ID that match the token's project. Keep the project with each stored token and pick the matching credentials when you send. Firebase also documents authorizing a service account from a different project.