The app asks for permission
iOS always shows a prompt; Android 13 and later need the POST_NOTIFICATIONS runtime permission.
APNs is Apple's service for delivering push notifications to iPhone, iPad, Mac and Apple Watch; FCM is Google's free service for Android, which can also send to iOS (through APNs) and web browsers. Every push to an Apple device ultimately goes through APNs, so the real choice is whether your backend talks to APNs directly for iOS or sends everything through FCM. Both cap payloads at 4 KB, both are free, and both deliver on a best-effort basis, so reliable notifications depend on token management, the right priority and time-to-live, and an app that refreshes state when opened. For most apps, we recommend FCM as one API for Android, iOS and web, with direct APNs only when you need iOS-specific features such as Live Activities or VoIP at scale.
A quick comparison of APNs and FCM, highlighting their key features, platform compatibility, and differences in push notification delivery.
| Comparison | APNs (Apple Push Notification service) | FCM (Firebase Cloud Messaging) |
|---|---|---|
| Owner | Apple | |
| Devices | iPhone, iPad, Mac, Apple Watch, Apple TV, Vision Pro, Safari web push | Android, iOS (via APNs), web browsers |
| Cost | Free with an Apple Developer account | Free |
| Server API | HTTP/2 provider API | HTTP v1 API (legacy APIs shut down in 2024) |
| Authentication | Token-based (.p8 key, signed JWT) or TLS certificate | OAuth 2.0 access token from a Google service account |
| Max payload | 4 KB (5 KB for VoIP) | 4 KB |
| Priority | 10 (immediate), 5 (power-aware), 1 (lowest) | High or normal |
| Expiry | apns-expiration timestamp | TTL up to 4 weeks |
| Replace older messages | apns-collapse-id (up to 64 bytes) | collapse_key (up to 4 active keys per device on Android) |
| Group sends | No topics; send per device or use broadcast for Live Activities | Topics and conditions, device groups |
| Silent/background push | content-available, throttled by iOS | Data-only messages, limited by Android background rules |
| Rich media | Notification Service Extension with mutable-content | Image field, expanded layouts on Android |
| Analytics | Delivery status via Push Notifications Console | Delivery data and reports in Firebase console and BigQuery export |
Understand how push notifications travel from your server through APNs or FCM to a user’s device, enabling timely alerts, real-time updates, and better app engagement across platforms.
This process involves device tokens, notification payloads, and platform-specific services to ensure messages reach users efficiently, even when the app is running in the background.
iOS always shows a prompt; Android 13 and later need the POST_NOTIFICATIONS runtime permission.
iOS returns an APNs device token; Android (and iOS when using the Firebase SDK) returns an FCM registration token.
along with the user ID, platform, app version and environment.
to APNs or FCM with the token, the payload and delivery options such as priority and expiry.
over a persistent connection the operating system keeps open, so your app does not need to be running.
depending on the message type, the app state and the user's notification settings.
Create an APNs authentication key (.p8) in your Apple Developer account and sign a JSON Web Token with it for each connection. One key works for all your apps and never expires; the older certificate method needs yearly renewal per app.
Send to the development (sandbox) endpoint for debug builds and the production endpoint for TestFlight and App Store builds. Tokens from one environment do not work in the other.
apns-topic (your bundle ID), apns-push-type (alert, background, voip, liveactivity and others), and optionally apns-priority, apns-expiration and apns-collapse-id.
A JSON aps dictionary with alert (title, subtitle, body), badge, sound, thread-id, interruption-level and relevance-score, plus your own keys.
Add your Android and iOS apps to a Firebase project and include the Firebase Messaging SDK.
Your server uses a Google service account to get short-lived OAuth 2.0 access tokens for the HTTP v1 API, usually through the Firebase Admin SDK.
Upload your APNs .p8 key to the Firebase project; FCM then forwards iOS messages to APNs for you.
Notification messages (shown by the system when the app is in the background), data messages (handled by your app code), or both, with platform-specific android, apns and webpush blocks for fine control.
Explore how APNs and FCM structure notification payloads, handle message data, and support custom content to deliver relevant alerts and personalized user experiences across mobile platforms.
| Comparison | APNs | FCM |
|---|---|---|
| Maximum size | 4,096 bytes (5,120 for VoIP) | 4,096 bytes |
| Display fields | aps.alert: title, subtitle, body | notification: title, body, image |
| Custom data | Any extra JSON keys outside aps | data: string key-value pairs only |
| Badge | aps.badge (number) | Android: notification count; iOS via apns block |
| Grouping | thread-id | tag (Android), thread-id via apns block |
| Interruption level | passive, active, time-sensitive, critical | Android notification channel importance |
Compare how APNs and FCM manage notification delivery, including priority settings, message expiration, delivery timing, and platform-specific controls that help developers send alerts reliably.
| Control | APNs | FCM |
|---|---|---|
| Priority | 10 = deliver now and wake the device; 5 = deliver when power-efficient; 1 = lowest | high = deliver now, may wake the device; normal = may wait for the device to wake |
| Expiry | apns-expiration (0 = try once, then discard) | ttl, from 0 seconds up to 4 weeks (default 4 weeks) |
| Replace older messages | apns-collapse-id: newer message replaces the older one | collapse_key: up to 4 different keys held per Android device |
| Offline storage | Keeps only the latest notification per app when the device is offline | Stores messages until TTL expires (subject to limits) |
| Throttling | Background pushes limited by iOS; too many high-priority pushes get throttled | High-priority messages that don't show a notification can be downgraded to normal |
APNs content-available pushes and FCM data-only messages wake your app to refresh content. Both operating systems limit them to protect battery: Apple recommends no more than a few per hour, and Android may delay them under Doze and battery optimisation.
On iOS, set mutable-content and use a Notification Service Extension to download images, decrypt content or change the text before it shows. On Android, FCM's image field and custom layouts give expanded notifications.
iOS notification categories and Android notification actions let users reply, approve, track or snooze without opening the app.
Live Activities on the lock screen and Dynamic Island are updated by APNs liveactivity pushes, including broadcast updates to many users at once; FCM can send these through its apns block.
iOS VoIP pushes through PushKit must report an incoming call with CallKit immediately. Android uses high-priority FCM data messages with a full-screen intent.
FCM supports web push for Chrome, Firefox and Edge. Safari, including web apps added to the iPhone home screen from iOS 16.4, uses the standard Web Push protocol.
tokens change after reinstalls, restores and refreshes; APNs returns 410 Unregistered and FCM returns UNREGISTERED for dead ones.
sandbox tokens sent to production APNs, an expired certificate, or the wrong Firebase project.
or invalid JSON.
notifications denied, Focus or Do Not Disturb, disabled Android channels, battery savers.
background pushes delayed or dropped by the OS.
messages received in the foreground but never displayed by the app.
many newer Huawei phones cannot receive FCM and need Huawei Push Kit.
Identify and resolve common push notification issues with a practical checklist covering device tokens, permissions, payload formatting, authentication, and delivery errors across APNs and FCM.
Use these troubleshooting steps to diagnose failed notifications, verify server configurations, and improve reliable message delivery on iOS and Android devices.
your server used is the latest one the app reported for that user and device.
and store the error code with every send.
(title and body only) to separate transport problems from payload problems.
APNs key, team ID, bundle ID and endpoint; FCM project and service account.
permission, Focus mode, Android channel importance, battery restrictions.
in foreground, background and killed states.
Apple's Push Notifications Console and Firebase's message delivery reports show where a message stopped.
Choose the right push notification setup based on your target platforms, app architecture, delivery requirements, and development resources to ensure reliable communication across iOS and Android devices.
| Your situation | Recommended setup | Why |
|---|---|---|
| Android and iOS app, standard notifications | FCM for both platforms | One API, one token type, topics and analytics in one place |
| iOS-only app | APNs directly | No extra dependency; full access to every APNs feature |
| Heavy use of Live Activities, VoIP or time-sensitive iOS alerts | APNs directly for iOS, FCM for Android | Full control of APNs headers and push types |
| Users on Huawei devices without Google services | Add Huawei Push Kit alongside FCM | FCM cannot reach these devices |
| Marketing campaigns, segmentation, A/B tests | A messaging platform (OneSignal, Braze, Airship, CleverTap, MoEngage) on top of APNs and FCM | Segments, journeys and analytics without building them |
| Very high volume or strict data control | Your own notification service talking to APNs and FCM | Control of queues, retries, logging and data residency |
Need push built into your app? See our iOS app development services, Android app development services and Firebase iOS app development.
free to use; APNs only needs your Apple Developer Program membership.
free tiers for small apps, then monthly fees that grow with users and channels.
basic push for one app typically takes 1–2 weeks of development ($2,000–$6,000); a custom notification service with preferences, scheduling, segments, rich media, Live Activities and analytics costs $10,000–$40,000.
Send the token on every app start, store it with user, platform, environment and last-seen time, update it on refresh, remap it on logout, and delete it on unregistered errors.
Stay well under 4 KB; send IDs, not full records, and let the app fetch details.
High priority only for messages the user must see now; short expiry for time-sensitive alerts such as OTPs and ride updates.
Explain the value first (order updates, price alerts) and ask after a related action, not on first launch.
Notification preferences by type, quiet hours, Android channels and iOS interruption levels reduce opt-outs.
Delivery is best-effort; important information must also be in the app and, where needed, by SMS or email.
Log sends, provider responses, deliveries, opens and opt-outs to find problems and improve engagement.
Avoid sensitive data in visible notification text; encrypt content and decrypt it in a Notification Service Extension when needed.
Our iOS, Android and backend engineers set up APNs and FCM, token management, rich and silent notifications, Live Activities and delivery analytics, and fix pushes that go missing. Tell us about your app and we'll send a recommended setup, timeline and cost within 2 business days.