Push notifications: troubleshooting and pitfalls
Push notifications: troubleshooting and pitfalls
A push integration spans four independent systems: your mobile app, the Firebase Console, FCM/APNs, and the SMSBAT backend. Most trouble comes from the fact that when one of them breaks, it usually fails silently or returns a misleading error.
This page collects the traps worth knowing in advance and a procedure for diagnosing a live failure.
1. Three identifiers people mix up
| Identifier | What it looks like | What it is for |
|---|---|---|
| Firebase Installation ID (FID) | fA9kQ2xRTb2mLp0WYs4nEv | Identifies an installation. Upsert key. Not a send target. |
| FCM registration token | fA9kQ2xRTb2mLp0WYs4nEv:APA91b… (~163 chars) | The only value message.token accepts for delivery. |
| Expo push token | ExponentPushToken[...] | Expo’s own token. Not used by the SMSBAT Push API. |
The FCM token starts with the FID
That shared prefix is exactly why the two get swapped in code. If a value is about 22 characters long, it is a FID; a registration token is far longer and contains a colon.
2. Seven integration traps
1. RNFirebase v26 removed the messaging() call
In @react-native-firebase/messaging v26+ the old namespaced syntax returns
undefined.
-
Symptom:
Object is not a functionwhen requesting a token. -
Fix: use the modular API only:
import { getMessaging, getToken, getAPNSToken } from '@react-native-firebase/messaging'; const msgInstance = getMessaging(); const fcmToken = await getToken(msgInstance);
2. One try/catch around both the FID and the token
If you fetch the FID and the FCM token in the same try block and getToken()
throws — which it often does on iOS before permission is granted — you lose both.
- Fix: fetch them in separate
try/catchblocks. A missing token must not blockregisterInstallation.
3. The APNs token arrives late on iOS
registerDeviceForRemoteMessages() resolves as soon as the request is made. The
APNs token itself comes back from Apple later.
- Fix: poll
getAPNSToken()(10 attempts, 500 ms apart) before callinggetToken().
4. Two push services competing on Android
If the app contains both expo-notifications and
@react-native-firebase/messaging, two FirebaseMessagingService entries end up
registered in AndroidManifest.xml.
- Symptom: Android hands the push to one of them only. If RNFirebase wins
while your listener sits in Expo, no banner appears and no
deliveredcallback is sent. - Fix: subscribe at both levels and de-duplicate on
data.guid.
5. Data-only messages are not drawn by the system
SMSBAT sends data-only messages so the app can report delivered before the
user opens anything.
- Symptom: no system banner appears, even though the push arrived.
- Fix: the app must draw the local notification itself, in both background and foreground.
6. Sending a FID where a token is expected
Send test message in the Firebase Console accepts a FID because it converts it internally. The REST API v1 does not — it requires an FCM registration token.
- Symptom:
404 UNREGISTEREDfor a bare FID in the token field.
7. Token rotation
Reinstalling the app or clearing its data produces a new FID and token.
- Fix: upsert on
externalUserId+platform, and deactivate the stale installation as soon as FCM answersUNREGISTERED.
3. Diagnosing a live failure
When push does not arrive, or the cascade does not stop, walk the chain in order — each step tells you which of the four systems to blame.
- Is there a token on the device? Show it on a diagnostics screen in the app. Empty means the problem is in the mobile code or in the OS permission, and nothing further down matters yet.
- Does a direct cURL request to FCM V1 arrive? If it does, the app and the Firebase keys are fine and the problem is on the sending side.
- Do you see
SenderIdMismatch? Thegoogle-services.jsonin the app belongs to a different Firebase project than the service account JSON in SMSBAT. - Do you see
ThirdPartyAuthError? The Firebase service account expired or was revoked. Upload a fresh JSON in the Omni panel and press the refresh button on the integration.
Build the diagnostics screen first
A screen showing the FID, the FCM token, the APNs token, the permission state and the last registration response answers step 1 in seconds. Without it, every report becomes guesswork.