Mobile push notification architecture is the system that turns a real business event—such as a booking change, payment status, security alert or reminder—into a useful, safe action for the right person. A provider integration alone is not that system. Reliable iOS and Android push notifications require coordinated ownership of event creation, device registrations, preference checks, queued delivery, deep-link routing and operational evidence.

That distinction matters after launch. A server can receive a successful response from a messaging provider while the user has disabled permission, the device token is stale, the app cannot open the target screen, or a retry has produced a duplicate alert. Design for the full journey rather than treating “sent” as the end state.

Model push as an event-to-action pipeline

A practical architecture starts with an authoritative business event and ends with a verified in-app outcome:

  1. A source-of-truth service records a change, for example a reservation moves from confirmed to cancelled.
  2. In the same transaction, it writes a notification intent to an outbox table or publishes a durable event.
  3. A notification worker evaluates recipient eligibility: account state, notification permission, category preferences, quiet hours, locale, timezone and active registrations.
  4. The worker creates a deduplicated delivery intent and submits platform-specific payloads through its trusted server environment.
  5. The mobile app handles foreground, background and terminated-state behavior, then resolves a safe route when the user taps.
  6. Telemetry records what is actually known at every stage, rather than inferring user delivery from a provider response.

Keep these responsibilities separate. FCM routes a message through platform transport and the on-device SDK handles it according to application state and app logic; provider acceptance is therefore not proof that the person saw an alert or reached the intended content.

Manage the device registration lifecycle, not a permanent “user token”

A user can have several devices, reinstall the app, change accounts on a shared phone or revoke notification access. Treat the registration as an app-installation record, not as a durable user identity. A useful record includes an internal registration ID, user ID, platform, app version, FCM registration/Firebase Installation ID where applicable, APNs environment, permission state, locale, IANA timezone, last-seen time and invalidated-at time.

On app start and whenever the platform callback reports a current token or registration, send it to your backend and update its freshness timestamp. Do not create another row for the same installation unless the identity truly changed. When a provider reports an unregistered or invalid target, deactivate it immediately and stop retrying that target. Firebase specifically recommends storing current registration identifiers with timestamps, refreshing server-side knowledge, and removing invalid or stale registrations; its current documentation also notes that Android registrations inactive for a long period can expire.

Account transitions and data minimisation

On logout, disassociate the installation from the account and remove account-specific topic or segment membership. On a subsequent login, reattach it only after the session is valid. Otherwise, a previous user of a shared device can receive alerts intended for the next account holder.

Never put secrets, one-time passcodes, full financial data or sensitive document details in a push payload. A notification should carry a short, non-sensitive summary plus a signed or opaque identifier. After a tap, the app should authenticate, authorise and retrieve current data from the API. This also prevents old notifications from presenting obsolete state as if it were current.

Prevent duplicate sends with idempotency and supersession

Duplicates usually originate upstream: a webhook is redelivered, two services react to the same state change, a queue consumer restarts after an uncertain timeout, or a human triggers a bulk campaign twice. Give every logical alert a deterministic idempotency key, such as notification_type + entity_id + entity_version + recipient_id + channel, and enforce a unique database constraint on it.

  • For a status update, use an immutable event ID or monotonic entity version—not only the current status text.
  • Store one logical notification intent and separate per-registration delivery attempts beneath it.
  • Retry only transient failures, with bounded backoff and a dead-letter/exception workflow; an invalid registration is a cleanup action, not a retry condition.
  • Apply a supersession rule: a delayed “booking changed” alert should be cancelled if a later event makes it irrelevant or the user has already acknowledged the change.

Platform collapse or grouping features can reduce notification-tray clutter, but they do not replace server-side idempotency. Your system still needs to answer which business event created the alert, whether it was suppressed, and which devices were targeted.

Design preferences, segmentation and timezone logic as product rules

A single “allow marketing notifications” toggle is inadequate for most products. Store category-level choices for security, transactional updates, reservations, reminders and product news. Define which categories are mandatory or legally governed before implementation; do not silently treat promotional content as transactional.

Build eligibility in your backend rather than making provider topics your only audience model. Persist the rule version, evaluation time and reason a recipient qualified. This makes an unexpected send explainable and allows a preference change to take effect before the next delivery attempt.

Use IANA timezone names such as America/New_York, not only a fixed offset. “9:00 AM local time” and “24 hours before the appointment” are different scheduling rules, and daylight-saving changes make fixed UTC offsets unsafe for many audiences. For reminder products, define a missed-send policy too: if a device comes online after the desired time, should the reminder send immediately, expire, or become an in-app item only?

Make mobile deep link implementation defensive

Do not make a push payload a fragile instruction like “open screen 12.” Carry a versioned route intent: for example, route=booking_detail, booking_id and route_version=1. A central router should validate the route, establish the session, check access, fetch current data and then navigate. If the object no longer exists, the account lacks access or the installed app does not support that route version, open a safe fallback such as the bookings list, notification inbox or home screen.

Test each route when the app is foregrounded, backgrounded and terminated; when the user is signed out; when connectivity is absent; when data has changed since the push was created; and when the app is one or more supported releases behind. Apple documents that a notification action can launch an app in the background and call the notification delegate, so routing must be lifecycle-safe and repeatable rather than dependent on one visible screen.

Do not treat silent pushes as guaranteed background jobs

Silent/background notifications can help an app refresh opportunistically, but operating systems may defer or limit background work based on device and system conditions. On Apple platforms, background pushes require the appropriate APNs push type and priority settings. Critical product state should therefore be reconciled when the app opens or resumes from its authenticated API, not assumed correct because a silent push was sent.

If a reminder or account event is truly important, push should be an attention channel—not the only source of truth. Keep an in-app inbox, activity history or status page that the user can consult later.

Build notification delivery monitoring around evidence

Measure at least four separate stages: planned (a policy qualified the event), submitted/accepted (the provider accepted the request), device-delivered (where SDK telemetry is available), and opened/actioned (the app recorded a relevant user action). These stages answer different questions. A high provider-acceptance rate cannot demonstrate that a deep link worked.

Log an internal notification ID, idempotency key, source event ID, provider message ID, platform, app version, category, route version, attempt number, response code and timestamps. FCM can export individual message acceptance and device-SDK delivery signals to BigQuery, while its aggregated Android delivery data helps identify transport-level failure patterns. Treat stale registrations as a reporting-quality issue as well as a cost and efficiency issue.

Alert on shifts, not just absolute counts: a sudden rise in invalid registrations, permission-denied recipients, route fallbacks, expired queued messages, retry volume or a drop in opens for one app version often identifies a release or integration defect earlier than support tickets do.

Use retries and fallback channels without spamming people

Retries should be technical, bounded and invisible to users. A failure to submit because of a temporary provider or network error may warrant retry; an expired alert should not be delivered hours later merely because a queue recovered. For user-facing resilience, define escalation by event type, urgency and consent: an in-app record is the durable baseline; push attracts attention; email or SMS may be appropriate only for genuinely important events and only within applicable preferences and policy.

Release checklist for push notification development

  • Registration refresh, logout disassociation and invalid-target cleanup are implemented.
  • Every critical event has an idempotency key, retry policy and supersession rule.
  • Category preferences, consent history and quiet-hour rules are auditable.
  • Timezone tests use real IANA zones and daylight-saving transitions.
  • Deep links are versioned, authorised and covered by fallback routes.
  • Foreground, background and terminated behavior is tested on both iOS and Android.
  • Monitoring distinguishes intent, provider acceptance, delivery telemetry and user action.

At POLADO, mobile app development includes the backend, UX and operational design needed for dependable notifications—not just a provider SDK setup. See a mobile product example in Car City, or combine a notification audit with technical support and consulting for monitoring, release safety and incident readiness. If your product already has duplicate sends, failing deep links or unexplained delivery gaps, contact POLADO to discuss a focused architecture review.