Compatibility
Compatibility lab results: frameworks, platforms, iOS modes and notification types.
Pushtifly tests each framework at two levels:
- Automated, on every server or SDK release. The server sends to an FCM and APNs simulator, and the exact payload the device would receive is verified. It also checks that each framework's SDK interprets it the same way (id, deep link, buttons, media and data).
- On real devices: a physical Android, an iPhone with an Xcode build (sandbox) and TestFlight (production), with the app in the foreground, in the background and closed.
Last automated run: 2026-11-02 — 120 of 120 cases passed (1220 checks).
Automated verification
Types: visible (with text, buttons, deep link, data and image), data (data_only: the text travels in data) and silent (silent).
| Framework | Android (FCM) | iOS (direct APNs) | iOS (via FCM) | Installation ID (FID) |
|---|---|---|---|---|
| Native (Android / iOS) · official SDK | ✔ visible, data, silent | ✔ visible, data, silent | ✔ visible, data, silent | ✔ visible, data, silent |
| Native (Android / iOS) · without SDK (REST) | ✔ visible, data, silent | ✔ visible, data, silent | — | — |
| Ionic + Capacitor · official SDK | ✔ visible, data, silent | ✔ visible, data, silent | — | — |
| Ionic + Capacitor · without SDK (REST) | ✔ visible, data, silent | ✔ visible, data, silent | — | — |
| Cordova · official SDK | ✔ visible, data, silent | ✔ visible, data, silent | ✔ visible, data, silent | — |
| Cordova · without SDK (REST) | ✔ visible, data, silent | — | ✔ visible, data, silent | — |
| Flutter · official SDK | ✔ visible, data, silent | — | ✔ visible, data, silent | ✔ visible, data, silent |
| Flutter · without SDK (REST) | ✔ visible, data, silent | — | ✔ visible, data, silent | ✔ visible, data, silent |
| React Native · official SDK | ✔ visible, data, silent | — | ✔ visible, data, silent | ✔ visible, data, silent |
| React Native · without SDK (REST) | ✔ visible, data, silent | — | ✔ visible, data, silent | ✔ visible, data, silent |
| Expo · official SDK | ✔ visible, data, silent | — | ✔ visible, data, silent | ✔ visible, data, silent |
| Expo · without SDK (REST) | ✔ visible, data, silent | ✔ visible, data, silent | — | — |
"—" means that integration doesn't produce that token type: for example, firebase_messaging always delivers FCM on iOS.
Installation ID (FID): recent Firebase SDKs replace the registration token with the Firebase Installation ID. Pushtifly recognizes it and sends it in message.fid. The column summarizes Android and iOS via FCM in the integrations that can already use it.
Each case checks:
- provider and APNs environment;
_phidand_ph;- flat keys according to the payload profile;
- text, translated buttons, category and
mutable-contenton iOS; - native image (Android and
fcm_options), channel and priority; - size under 4 KB.
What each integration covers
| Integration | With the app open | Buttons | Images | Opens and clicks |
|---|---|---|---|---|
| Official SDK | Yes | Android with the app open; iOS with the extension | Yes (iOS with the extension) | Automatic |
| Without SDK (REST) | Depends on the plugin | Your own implementation | Android yes; iOS with your own extension | Call /v1/events |
Payload profiles
Without an SDK, each plugin reads the data differently. Pushtifly adjusts the payload to the app's framework. With an official SDK, the device only receives _phid and _ph.
| Profile | Flat keys | Text in data-only messages |
|---|---|---|
| Official SDK | none | title, body |
| Capacitor, Flutter, React Native, native, others | deepLink, imageUrl |
title, body |
| Cordova | deepLink, imageUrl, image |
title, message |
| Expo | deepLink, imageUrl |
title, message |
Tests on real devices
Visible notification in each app state.
| Framework | Android foreground | Android background | Android closed | iOS foreground | iOS background | iOS closed |
|---|---|---|---|---|---|---|
| Native (Android / iOS) · official SDK | pending | pending | pending | pending | pending | pending |
| Native (Android / iOS) · without SDK (REST) | pending | pending | pending | pending | pending | pending |
| Ionic + Capacitor · official SDK | pending | pending | pending | pending | pending | pending |
| Ionic + Capacitor · without SDK (REST) | pending | pending | pending | pending | pending | pending |
| Cordova · official SDK | pending | pending | pending | pending | pending | pending |
| Cordova · without SDK (REST) | pending | pending | pending | pending | pending | pending |
| Flutter · official SDK | pending | pending | pending | pending | pending | pending |
| Flutter · without SDK (REST) | pending | pending | pending | pending | pending | pending |
| React Native · official SDK | pending | pending | pending | pending | pending | pending |
| React Native · without SDK (REST) | pending | pending | pending | pending | pending | pending |
| Expo · official SDK | pending | pending | pending | pending | pending | pending |
| Expo · without SDK (REST) | pending | pending | pending | pending | pending | pending |
Your framework isn't listed? Any app that gets an FCM or APNs token works via REST.