Firebase Cloud Messaging is the standard way to send push notifications to Android apps, and it has the same two security details as any push system: the registration token that identifies where to send, and the payload that travels to the device. The common mistakes mirror iOS: putting sensitive data in the message payload, where it passes through Google's infrastructure and can show on screen, and embedding your FCM server credentials in the app, where they do not belong. Here is how FCM tokens and payloads work and how to handle both securely.
Short answer
Firebase Cloud Messaging (FCM) delivers push notifications to apps via Google's infrastructure. Per Firebase's documentation, the registration token identifies an app installation and should be treated as an identifier your server stores and validates, while your FCM server credentials, the service account used by the HTTP v1 API, must stay on your server, never in the app. Do not put sensitive data in the message payload, since it passes through FCM and can be displayed on screen; send a minimal payload and have the app fetch sensitive details from your backend. Treat data messages as input to validate, keep server credentials server-side, and keep sensitive data out of the payload.
What you should know
- FCM delivers push via Google's infrastructure: through a registration token.
- The token is an identifier: store and validate it server-side.
- Server credentials stay server-side: never embed the FCM service account in the app.
- Do not put sensitive data in the payload: it passes through FCM and can show on screen.
- Validate data messages: treat their contents as input.
How do registration tokens and server credentials work?
The token is FCM's address for an app installation, and the server credential is what authorizes you to send. The Firebase SDK gives your app a registration token, which you send to your backend, and your backend uses it, with its FCM credentials, to ask Google to deliver a message to that installation. The token is not exactly a secret, but it identifies an installation and can change, so treat it as an identifier you store securely, associate with the right user, validate, and refresh when it rotates, rather than something to log or expose. What must stay protected is your FCM server credential, the service account key used by the HTTP v1 API to send on your behalf; that belongs only on your server, never embedded in the app, because anything in the app can be extracted, and an exposed credential would let someone send messages as you.
What should you not put in the payload?
Anything sensitive, because the payload is not a private channel. The table shows the concern.
| Payload content | Risk |
|---|---|
| Sensitive personal data | Passes through FCM and can show on screen |
| Tokens or credentials | Exposed in transit and on the device |
| Full message contents | May be visible before the user authenticates |
| A minimal identifier or hint | Acceptable; details fetched securely afterward |
The message payload travels through FCM, so Google's infrastructure handles it, and notification messages can be displayed on the device before the user opens the app, so treating the payload as private is a mistake. A push message should carry only what is needed to alert the user and tell the app what to load, not the sensitive content itself, which is the same principle that applies to iOS push.
How do you send sensitive notifications safely?
Send a minimal payload, then fetch the sensitive details over your secure channel. Include in the message only what is necessary to notify the user and tell the app what to retrieve, an identifier or a generic hint, and have the app fetch the actual sensitive content from your backend over HTTPS once the user engages, where your authentication and access control apply. Keep your FCM server credentials on your server, store registration tokens securely and tied to the right user, and treat data messages your app receives as input to validate rather than trust, since you should not assume a message's contents are well-formed or benign. Design the visible notification text so a lock-screen preview does not reveal something private. The principle is that the push is a prompt, and the sensitive data lives behind your authenticated backend.
What to watch out for
The first trap is putting sensitive data in the FCM payload, which passes through Google's infrastructure and can show on screen; send a minimal payload and fetch details securely. The second is embedding your FCM server credentials, the service account, in the app, where they can be extracted; keep them server-side. The third is treating registration tokens carelessly or trusting data-message contents without validation. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK or AAB against OWASP MASVS and surfaces hardcoded secrets and how the app handles data, so you can confirm no FCM server credential is embedded and sensitive data is not mishandled. The payload and token design you implement in the app and backend.
What to take away
- FCM delivers push via Google's infrastructure using a registration token, which is an identifier your server stores and validates, while your FCM server credentials must stay server-side.
- Do not put sensitive data in the message payload, since it passes through FCM and can be displayed on screen.
- Send a minimal payload to prompt the user, fetch sensitive details from your backend over HTTPS, and validate data-message contents.
- Keep FCM credentials off the device, and use a pre-submission scan such as PTKD.com to confirm no server credential is embedded.


