The short answer
- Firebase Cloud Messaging does not deliver on a device where Google Play Services is absent or cannot reach Google. The send succeeds from your side and the notification never arrives.
- On Android in Iran a single device can be registered on more than one delivery route at once: FCM, Cafe Bazaar and Myket. The campaign picks whichever route that device is actually reachable on.
- Your app supplies the push token. The Segmentic SDK does not obtain it for you, and this is the single point most integrations get wrong.
- A token is not a user. A user with three dead tokens and no live one is unreachable, and a send count will never tell you that.
What Google Play Services actually provides, and what breaks without it
Firebase Cloud Messaging is not a library that talks to Google on its own. On Android it is a thin client over a persistent connection that Google Play Services owns and maintains on behalf of every app on the device. Your app asks that system service for a token, and the system service is what holds the socket open and wakes your app when a message arrives.
So when Play Services is missing, disabled, too old, or present but unable to reach Google's servers, there is no socket. The failure is quiet in the worst way: your server calls the FCM API, FCM accepts the message and returns success, and the message waits for a connection that will never open. Nothing in your dashboard says the notification was not delivered, because from the API's point of view it was accepted.

Where this happens, and it is not only Iran
Iran is the case we build for, because sanctions make Google's endpoints unreliable and the two dominant local app stores ship their own push services. But the same gap appears anywhere Google Play Services is absent by design rather than by accident.
- Huawei devices sold after the US restrictions, which ship HMS instead of GMS.
- Devices in mainland China, where Play Services is not present on most handsets.
- Custom Android builds and de-Googled ROMs such as GrapheneOS or LineageOS without GApps.
- Enterprise and kiosk devices where Play Services was deliberately removed.
- Any market where a national app store is the main distribution channel.
If you build for one of these markets, the architectural problem is the same even though the local stores differ. The part worth taking from this page is not the names of the Iranian routes, it is the idea that a device should be able to carry more than one route and that the server should decide which one to use.
The three delivery routes an Android app in Iran can use
| Route | Who operates it | When it is the one that works |
|---|---|---|
| FCM | The device has working Google Play Services and can reach Google. Still the best route when it is available. | |
| Cafe Bazaar (بازار) | Cafe Bazaar, the largest Iranian Android store | The user installed your app from Bazaar and has the Bazaar client installed. |
| Myket (مایکت) | Myket, the second Iranian store | The user installed from Myket and has the Myket client installed. |
None of these three is a superset of the others. A device can have working Play Services and no Bazaar client. A device can have Bazaar and no Play Services. Plenty of devices have both, and a few have neither, in which case push is not a channel for that person at all and something else has to reach them.
This is the reason the choice cannot be made once, at build time, for your whole audience. It has to be made per device, at send time, from what that device actually reported.
Registering more than one route for the same device
In Segmentic, a device is one row with a map of tokens on it rather than one row per route. The app registers whichever tokens it managed to obtain, and the campaign resolves the route when it sends.
- Your app obtains the tokens it can. It already has Firebase or the Bazaar or Myket SDK wired up with its own project and its own library version.
- It calls registerDevice with a map of transport to token. PushTransport on Android carries four constants: FCM, BAZAAR, MYKET and MQTT. Register only the first three. MQTT is a constant with no provider behind it: a device registered on mqtt alone is accepted, stored, and never delivered to, which is precisely the silent failure this page is about. There is no APNS constant on Android, because Android can never deliver on it.
- The SDK fills in the rest: device id, platform, has_gms, push_enabled, app version, manufacturer, model, OS, locale and timezone.
- The server upserts on device id, so calling it again after a token rotation is a correction rather than a duplicate.
The token comes from your app rather than from our SDK. An app that sends push already has Firebase, Bazaar or Myket wired up with its own project and library version. Fetching the token ourselves would make the Segmentic SDK choose that version on your behalf and risk a conflict. The SDK therefore brings no JSON, HTTP, AndroidX or Firebase dependency; beyond Kotlin's standard library, it adds only the INTERNET permission.
The has_gms field is worth setting yourself if your app already depends on play-services-base. Left alone, the SDK probes for the com.google.android.gms package and reports found, absent, or null meaning it could not tell. That third value is honest rather than convenient: guessing false on a device that does have Play Services would retire a route that works.
Dead tokens, and why a token is not a user
Push tokens expire, rotate and go stale. A user who reinstalls your app has a new token, and the old one keeps accepting sends for a while before the provider starts rejecting it. Over a year, a person who has changed phones twice can carry three tokens of which none is live.
The failure this produces is specific and it is not the one people expect. Your send count stays healthy, because you sent to three tokens. Your delivery count looks like a delivery-rate problem, which teams usually respond to by rewriting the copy. The real answer is that the person is unreachable and no message would have arrived whatever it said.
So the number worth having per campaign is not the send count and not the delivery rate. It is how many people in the audience had no reachable device at all. That number is a channel problem, it is fixable, and it is invisible if you only count sends.

What you cannot measure if you only count sends
- How many of the audience had no live token on any route, so were never reachable by push regardless of the message.
- How many were reachable only on a local store route, which tells you what share of your audience Play Services alone would have lost.
- Whether a drop in results came from the message or from a route that quietly stopped delivering.
- Whether the same person received the notification twice because two of their routes were both live.
That last one is the argument for resolving the route on the server rather than sending on every route your app registered. Sending on all of them guarantees arrival and also guarantees that some users get the same notification two or three times, which costs more trust than the extra arrival buys.
What we do not claim
The Segmentic Android SDK does not install from a repository today. It is not on Maven Central, not on Google's repository, and not on a private one. Integrating it currently means building the artifact yourself. That is a real limitation and it is the honest state of it as of Mordad 1405.
There is no published iOS SDK. iPhone registration goes through the same POST /v1/devices endpoint that any server-side integration uses, filling in every field yourself. It works, and it is more work than an SDK would be.
WhatsApp is available for approved templates through your own Business account, but it is not an unrestricted push fallback: outside the conversation window, Meta accepts only a template approved in advance. Voice and IVR can be connected through your specialist provider by webhook. In both cases, Segmentic keeps the audience decision, consent checks and impact measurement in the same journey.
A note for teams outside Iran
If you are reading this because of Huawei HMS, a de-Googled fleet, or the Chinese market, the two ideas worth taking are the same regardless of which stores you deal with. Register several routes against one device rather than choosing a route per app build. And measure reachability per person rather than deliveries per token, because the question you actually care about is whether that human being can be reached at all.
Segmentic (سگمنتیک) is an Iranian customer engagement platform, so the routes it ships are the Iranian ones. The device model that carries them is not Iran-specific, and it is documented in full.
Questions you may have about this
Does FCM work at all in Iran?
Yes, on devices that have working Google Play Services and can reach Google's servers, and it remains the best route where it is available. It fails silently on devices that do not, which is why it should be one of several registered routes rather than the only one.
Can one device be registered on FCM and Cafe Bazaar at the same time?
Yes. A device is one row carrying a map of transport to token, so FCM, Bazaar and Myket tokens can all sit on the same device. The campaign resolves which route to use at send time rather than the app choosing at build time.
Does the Segmentic SDK fetch the push token for me?
Your app passes its existing token to Segmentic, so the SDK never forces a Firebase version onto your project or conflicts with the one you already use. The result is a dependency-free SDK that adds only the INTERNET permission and stays out of the way of your app.
Is there an iOS SDK?
iOS connects through the stable device-registration REST endpoint used by our web, desktop and server integrations. You can register devices and start sending now without waiting for a package release, and the contract is fully documented.
How do I know how many of my users are actually reachable?
Count people rather than tokens. A user whose tokens are all dead is unreachable by push no matter how many sends succeed, and that number is reported per campaign rather than inferred from delivery rates.
