Skip to content
Back to Blog
engineering6 min read

Push Notifications Done Right on iOS and Android

How to do push notifications right with FCM on iOS and Android: permissions, segmentation, deep links, and reliability that drive mobile engagement.

SummationWorks
Push Notifications Done Right on iOS and Android

Most apps treat push notifications as an afterthought: a switch you flip on near launch, a few "We miss you!" blasts, and a steady stream of users tapping "Turn off." Done well, notifications are one of the cheapest, highest-leverage channels for retention and revenue. Done badly, they are the fastest way to get muted, uninstalled, or reported. The gap between the two is mostly engineering and judgment, not luck.

This guide explains how to do push notifications right on iOS and Android, what the moving parts actually are, and the decisions that separate a channel users trust from one they silence.

How push actually works

Push notifications are not sent directly from your servers to a phone. They travel through platform gateways that own the connection to each device.

  • On Android, your backend sends a message to Firebase Cloud Messaging (FCM), which delivers it to the device.
  • On iOS, delivery goes through the Apple Push Notification service (APNs). In most stacks, you still route through FCM, which forwards to APNs so you have a single API for both platforms.
  • Web push uses the same FCM/browser-vendor pipeline through service workers.

The flow is consistent: a device registers and receives a device token, your app sends that token to your backend, and your backend stores it against the user. When you want to notify someone, you look up their tokens and ask the gateway to deliver. Tokens are not permanent. They rotate when the app is reinstalled, restored to a new device, or refreshed by the OS, so your backend must update them quietly in the background or you will be pushing into the void.

For most teams shipping on Flutter, React Native, or native, FCM is the practical default because it abstracts both platforms behind one SDK and one server API. It also handles topic subscriptions and device groups, which save you from rebuilding fan-out logic yourself.

Permission is the product

The single biggest mistake we see is asking for notification permission on first launch, before the user understands what the app does. On iOS, the system prompt can only be shown once meaningfully. If a user denies it, you cannot ask again from inside the app. They have to dig into Settings, and almost no one does.

The fix is a pre-permission primer: a screen you fully control that explains the specific value of notifications before the OS dialog appears.

  • Trigger the real prompt at a moment of demonstrated intent, not on launch. A food delivery app should ask after the first order, not before browsing.
  • Tell the user exactly what they will receive: "Order status and delivery updates," not "Enable notifications."
  • If they decline your primer, do not fire the system prompt. Ask again later when the value is clearer.

Android historically auto-granted permission, but Android 13 and later require a runtime permission too, so the same primer logic now applies across both platforms. Treating permission as a conversion funnel, with its own copy and timing, routinely lifts opt-in rates well above the naive first-launch approach.

Segmentation and timing beat volume

Once you have permission, restraint is what keeps it. The teams that win at mobile engagement send fewer, more relevant messages, not more of them.

Segment before you send

Blasting your entire user base the same message is the habit that trains people to ignore you. Segment by behavior and lifecycle:

  • New users who have not completed onboarding
  • Active users about to hit a meaningful milestone
  • Dormant users who were valuable and went quiet
  • Customers with an abandoned cart or an incomplete checkout

Each segment deserves different copy, a different trigger, and sometimes a different frequency cap.

Respect time and place

A notification at 3 a.m. local time is a one-way ticket to the off switch. Store each user's time zone and send within sensible local windows. For audiences across the GCC and Egypt, account for the working week and prayer-time sensitivities rather than assuming a Western schedule. Localize the message body too, including right-to-left rendering for Arabic, so the notification looks native rather than bolted on.

Prefer triggered over broadcast

The highest-performing notifications are event-driven: a price drop on a watched item, a reply to a comment, an order out for delivery. These map to something the user already cares about, so relevance is built in. Broadcast campaigns have their place for genuine announcements, but they should be the exception, not the rhythm.

A notification that opens the app to a generic home screen wastes the tap. Every actionable notification should carry a deep link in its payload that routes directly to the relevant screen: the specific order, the specific chat, the specific product. This is also where notifications quietly fail in production, so it deserves real testing.

A few engineering details that matter:

  • Distinguish notification messages from data messages. Notification messages are rendered by the OS; data messages hand the payload to your app code so you can decide how to display or process it. Mixing them up causes notifications that silently disappear when the app is backgrounded.
  • Handle all three app states: foreground, background, and terminated. Behavior differs per platform and is the most common source of "it works on my phone" bugs.
  • Set channels and categories. Android notification channels and iOS interruption levels let users tune which categories they receive. Splitting transactional alerts from marketing protects your critical messages from being muted along with the promos.
  • Track delivery and engagement. Log sends, deliveries, opens, and the resulting in-app action. Without this loop you are guessing, and you cannot prune the campaigns that quietly annoy people.

For transactional reliability, treat critical notifications like any other important system call: retries, idempotency so a user is not buzzed twice for one event, and monitoring on token refresh failures.

Key takeaways

  • Route both platforms through FCM over raw APNs to keep one API, and keep device tokens fresh on your backend or delivery silently breaks.
  • Earn the iOS and Android permission with a value-first primer at a moment of intent, not on first launch.
  • Win mobile engagement through segmentation, local-time sending, and event-triggered messages, not higher volume.
  • Carry a deep link in every payload, separate notification from data messages, and use channels to protect transactional alerts.
  • Measure delivery, opens, and downstream actions so you can cut the campaigns that erode trust.

Push notifications reward teams that treat them as a product surface, not a megaphone. If you want a mobile app where notifications drive retention instead of uninstalls, SummationWorks can help architect the permission flow, FCM integration, segmentation, and deep linking end to end. Explore our services, browse our work, or get in touch to talk through your project.

About the author

SummationWorks

SummationWorks is a software development company building web apps, mobile apps, and AI tools for startups and growing businesses across the US, UK, and GCC.

More about us

Have a project in mind?

Let's turn your idea into production-grade software.

Start a Project