Push troubleshooting
Diagnose common Android push notification issues and understand FCM error codes.
This guide walks through the most common reasons notifications fail to arrive, delivery tracking gaps, build-time errors, and the FCM error codes you may encounter in server responses.
On this page
Nothing arrives on device
Work through this checklist in order:
google-services.json— confirm the file is in theapp/module root and matches the Firebase project you are using. Theproject_numberin the file must match the Sender ID configured in ZMP.- Firebase Messaging dependency — confirm
com.google.firebase:firebase-messagingis declared in yourapp/build.gradle. Without it, the device never registers for push. - Google Play Services — FCM requires Google Play Services on the device. Huawei-only devices or emulators without the Google APIs image do not receive FCM messages.
POST_NOTIFICATIONSpermission — on Android 13 (API 33) and above, the app must requestandroid.permission.POST_NOTIFICATIONSat runtime before notifications can be displayed. Without it, messages arrive but are not shown to the user.ZTPushServicedeclared in the manifest — the SDK ships aFirebaseMessagingServiceimplementation (ZTPushService) that should be declared in yourAndroidManifest.xmlwithpriority="-1"(the SDK default). If you use a customFirebaseMessagingService, confirm it forwards every incoming message toZTPush.handleMessage().
override fun onMessageReceived(remoteMessage: RemoteMessage) {
ZTPush.handleMessage(this, remoteMessage)
}
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
ZTPush.INSTANCE.handleMessage(this, remoteMessage);
}
Delivery tracking is not working
If notifications arrive and clicks register, but delivered events are missing in ZMP:
- Custom
FirebaseMessagingService— if you replaced or overrode the defaultZTPushService, confirm every incomingRemoteMessageis forwarded toZTPush.handleMessage(context, remoteMessage). The SDK records thedeliveredevent inside that call. - Service priority conflict — if your app declares another
FirebaseMessagingServicewith a higher priority thanZTPushService, the other service receives the messages first andZTPushServiceis never invoked. Either lower the other service's priority or forward messages manually. - SDK initialization timing — the SDK must be initialized before messages arrive. If
ZetaClient.initialize()is called lazily (for example, only after the user logs in), messages that arrive before initialization are not tracked. Initialize the SDK as early as possible, ideally inApplication.onCreate().
Build errors
| Error | Fix |
|---|---|
Duplicate FirebaseMessagingService | More than one FirebaseMessagingService is declared without priority disambiguation. Set android:priority="-1" on ZTPushService (SDK default) and a higher priority on your own service, or remove the duplicate. |
Missing google-services.json | Download from the Firebase console and place it in the app/ module root. The Gradle build fails at configuration time without it. |
Missing com.google.gms.google-services plugin | Add id("com.google.gms.google-services") to your app/build.gradle.kts plugins block (or apply plugin: 'com.google.gms.google-services' if using Groovy). |
FCM error codes
These errors are returned by Firebase Cloud Messaging when a push send fails. Some are caused by app-side configuration (marked Developer action); others originate at the provider layer (marked Escalate to Zeta).
Source: Firebase: ErrorCode reference and Firebase: Troubleshooting
Token errors
UNREGISTERED / NotRegistered (HTTP 404) — Developer action
The registration token is no longer valid. Common causes:
- The user uninstalled the app.
- FCM credentials were rotated on the Firebase project — devices registered with the old credentials hold stale tokens until the app re-registers.
- A second push service registration (via a different Sender ID) invalidated the token the SDK received.
- Custom app logic programmatically unregistered the device from push.
This error does not mean the user is push-disabled — only that a specific token was removed. It is common for testers who frequently install and uninstall the app.
InvalidRegistration (HTTP 400) — Developer action
The push token is malformed. Common causes:
- The app passed an Instance ID or another value instead of the token from
FirebaseMessaging.getInstance().token. - The app registers with multiple push services, and an intent from a different service produced an invalid token.
INVALID_ARGUMENT (HTTP 400, bad token) — Developer action
The registration token format is invalid, or the request contains other invalid parameters. Verify the token is the full string returned by the FCM SDK.
Authentication errors
MismatchSenderId / SENDER_ID_MISMATCH (HTTP 403) — Escalate to Zeta
The Sender ID used to send the message does not match the one tied to the registration token. This can also occur if the app registers with multiple push services using different Sender IDs.
Resolution: Confirm the Sender ID in your google-services.json matches the one configured in ZMP, then contact your Zeta account team.
THIRD_PARTY_AUTH_ERROR (HTTP 401) — Escalate to Zeta
The FCM server key or service account credentials are invalid or have been revoked. Contact your Zeta account team.
Payload errors
INVALID_ARGUMENT (HTTP 400, payload size) — Developer action
The notification payload exceeds the FCM limit (4 KB for notification messages, 4 KB for data messages). If you use Additional Values in the ZMP campaign builder, large or numerous key-value pairs can push the payload over the limit. Reduce the number or size of Additional Values.
Rate limiting
QUOTA_EXCEEDED (HTTP 429) — Informational
FCM enforces per-device, per-project, and per-topic rate limits. When exceeded, messages are queued and delivered when the quota resets. Common during bulk sends or testing.
The condition is temporary. If sustained, check your sending patterns for unintentional loops.
Server errors
| Error | HTTP | Description |
|---|---|---|
INTERNAL | 500 | An unexpected error on Google's side. Transient — retry the send. |
UNAVAILABLE | 503 | FCM is temporarily unable to process the request. Transient — retry with exponential backoff. |
See also
- Push Notifications — FCM integration, configuration, deep linking, FAQ.
- Firebase: ErrorCode reference
- Firebase: Troubleshooting
