← Blog · August 19, 2026

12 min read

I ran Firebase push notifications in production for a year — 6 things nobody warns you about

Firebase Cloud Messaging is the default answer for push notifications, and for good reason: it's free, it works on Android, iOS, and web, and the SDK gets you a "hello world" notification in an afternoon. Then you ship to real users, and the afternoon-demo version starts lying to you.

Your delivery rate slowly rots. A "successful" send reaches fewer people than last month and nothing in the dashboard explains why. You discover a hard API limit at the worst possible moment. None of this shows up in the quickstart guide, because the quickstart guide is written for the demo, not for month eleven. Here are the six things worth knowing on day one.

1. Your tokens are dying and FCM won't tell you

An FCM registration token is not permanent. It goes stale when a user reinstalls the app, clears app data, restores to a new device, or simply doesn't open the app for a long time. The part that catches people: FCM never proactively tells you a token died. You only find out at send time, buried in the per-message response, as a messaging/registration-token-not-registered error on that specific token. If you're not reading and acting on every send response, your device count looks healthy while your reachable device count quietly bleeds out. See stale FCM tokens for the full mechanism.

2. There's a hard 500-token limit, and you'll hit it mid-broadcast

The sendEachForMulticast API accepts a maximum of 500 tokens per call. Broadcasting to 10,000 devices isn't one API call — it's twenty, chunked. You have to handle partial failures, collect per-token error codes so you know which devices to prune, and retry transient failures without re-sending to the tokens that already succeeded. Get the retry logic wrong and a chunk of your users gets the same notification twice.

3. Token pruning is your job, and it's not optional

Once a send tells you a token is dead, you have to delete it from your database. FCM won't. Skip it, and every future broadcast keeps trying dead tokens — wasting API calls, inflating your "sent" numbers, and hiding the real health of your audience behind noise. The correct pattern is prune-on-send, not prune-on-a-schedule: a token only proves itself dead when you actually try to use it.

4. "Sent" is not "delivered" is not "seen"

FCM's response tells you the message was accepted for delivery. That's it. It does not mean the OS displayed it, and it does not mean a human saw it. Android battery optimization, Doze mode, iOS throttling for low-priority notifications, and the user's own settings all sit between "FCM accepted it" and "a person read it." If your analytics count success responses as opens, your open rate is fiction. Real open tracking means embedding a beacon in the payload and firing it when the app is actually opened from the notification.

5. FCM is a delivery pipe, not a notification platform

FCM does one thing well: the cryptographic last hop from your server to the device. It has no concept of a campaign, a schedule, a drip sequence, an audience segment, a dashboard a non-engineer can use, or A/B testing. Every one of those, you build and maintain yourself. That's not a criticism — it's a delivery primitive, and an excellent one. But if your mental model is "FCM is my push notification tool," you'll spend months rebuilding the same scheduling-and-segmentation layer every app eventually needs.

6. The migration trap: you may be more locked-in than you think

Many teams reach for a hosted push service to skip the work above. Reasonable — but most of them register your device tokens against their infrastructure. The day you want to leave, you can't just take your users with you: migrating off requires re-registering every device through a new SDK, and you only re-register the users who open the app again after your migration. The long-tail users are gone. You don't own your audience; you're renting it.

The alternative most people don't realize exists: keep FCM as your transport and add the platform layer on top of your own Firebase project. Your tokens stay in your tenant. You get the campaigns, scheduling, pruning, and AI copy without handing your audience to a vendor you can't leave.

The honest takeaway

Firebase Cloud Messaging is the right foundation — free delivery at any volume is not a deal you walk away from. But treat it as a foundation, not a finished product. You have three real options: build the platform layer yourself (fine if you have the engineering time), rent a hosted service (fast, but read the fine print on token ownership), or keep your own Firebase and add a strategy layer on top.

Pushbrain is built around that third path: it connects to your existing Firebase project and handles the pruning, batching, scheduling, A/B testing, and AI-written copy — while delivery stays on your own FCM, free, with your tokens staying yours. See Pushbrain vs raw FCM for the detailed breakdown. But whichever path you pick: read your send responses, prune your dead tokens, and never trust "sent" to mean "seen."

Bring your own Firebase. Start free.

No credit card required — connect your project and see reachability in minutes.

Get started free