A mobile app can send a push notification in a few lines of code. Building a notification system that people trust is a much larger product and engineering decision.
The difference becomes visible when a customer receives the same alert twice, a field worker misses an urgent assignment, a promotion arrives after it has expired, or a notification opens the wrong screen. None of these is primarily a problem with the wording of the message. They are problems with event design, recipient selection, delivery handling, permissions, app navigation and operational ownership.
For a product leader, the right question is not simply, “Can our app send push?” It is, “What must happen from the moment a business event occurs until the right user can take the right action, even when devices are offline and messages are delayed?”
This guide explains a practical architecture for transactional, operational and marketing push notifications across iOS and Android. It also identifies which responsibilities belong in the backend, which belong in the mobile client, and which cannot be guaranteed by a push provider.
The executive principle: a push notification is not the business transaction
A notification is a prompt to look at authoritative information. It should not be the only place where a critical assignment, approval, payment status or safety instruction exists.
Suppose a dispatcher assigns a new job. The system should first persist the assignment in its primary database. A notification can then tell the driver that a new job is available. If the push is delayed, suppressed by the operating system or never displayed, the assignment must still appear in the app’s task list when the driver opens it.
This distinction prevents a fragile architecture in which message delivery determines whether the business event “happened.” It also creates a useful fallback: in-app inboxes, task lists, email or SMS for selected workflows, and escalation rules where a missed action has real consequences.
Push is a best-effort delivery channel. Treat acknowledgement of a push request by a provider as evidence that the provider accepted the request, not proof that a person saw or acted on the message.
Start with the business event and the user action
Before choosing a push vendor, write down five things for every notification type: the triggering event, eligible recipient, intended action, useful lifetime and consequence of non-delivery.
A purchase confirmation may be informative and remain relevant for hours. A same-day shift change may need attention within minutes. A marketing offer may be useful only until its expiry time. A security alert may require a second communication channel or an explicit acknowledgement workflow.
The design should separate at least four classes:
- Transactional: receipts, order status, account changes and appointment confirmations.
- Operational: job assignments, approvals, exceptions, dispatch updates and urgent service changes.
- Engagement: reminders about incomplete but useful tasks or relevant content.
- Promotional: offers, campaigns and cross-sell messages.
These classes often need different preference rules, timing windows, escalation policies, retention periods and analytics. A single “send notification” function that treats every message identically makes future governance difficult.

A reference architecture that can be operated
A reliable design typically follows this sequence:
- A trusted business service commits an event, such as order_shipped or approval_requested.
- An event record or transactional outbox captures that event without relying on the push provider.
- A notification orchestration service determines whether a message should be created.
- Policy checks resolve the intended recipient, consent, preferences, frequency limits and suppression rules.
- A template renderer produces a short message and a stable, versioned deep-link destination.
- A durable queue holds eligible delivery jobs, including an idempotency key, expiry and attempt count.
- A worker submits messages to the appropriate provider, usually Firebase Cloud Messaging (FCM) or Apple Push Notification service (APNs), depending on the integration.
- Provider responses update an attempt log; retryable failures are rescheduled, while invalid tokens are deactivated.
- The mobile app handles the notification, opens the appropriate authenticated destination and records permitted interaction events.
- The business workflow continues to rely on its own authoritative state, not on whether the notification was tapped.
This design is intentionally modular. A small product may combine several components in one service. The important separation is logical: business events, policy decisions, delivery attempts and user actions should be observable independently.
Actiknow’s custom mobile application development services cover tailored mobile and enterprise applications; notification behavior should be scoped as part of the overall product workflow rather than left as an isolated messaging feature.

Persist the event before sending: the outbox pattern
One common failure occurs when an application updates its database and immediately calls a push API inside the same request. If the API call fails after the database commit, the business change exists but no alert is scheduled. If the database transaction rolls back after an external send, users may receive a message about something that never happened.
A transactional outbox addresses this mismatch. The business service writes the domain change and an event record in one database transaction. A separate worker reads committed outbox entries, publishes them to a queue and marks their publishing progress.
The queue and worker should tolerate duplicate publication. Use a stable event identifier and a deduplication rule such as event_id + notification_type + recipient_id. “Exactly once” delivery across databases, queues and device networks is not a realistic blanket promise. Aim instead for durable events, at-least-once processing and idempotent side effects.
An outbox is not always necessary for low-stakes marketing campaigns, but it is valuable when the push represents a meaningful operational event.
Recipient identity is not a device token
The backend should model people, accounts, app installations and provider tokens separately.
A user can have multiple devices. One device can be shared or reassigned. A token can rotate. An employee may change roles or lose access while a previously queued notification remains pending. An app may be reinstalled, and a customer may log out without uninstalling it.
A practical registration record can include an internal installation ID, authenticated user ID when signed in, platform, app version, push token, token update time, notification permission state where observable, and last-seen timestamp. Avoid storing unnecessary device identifiers.
On login, associate the installation with the authenticated user. On logout, revoke that association and clear sensitive local notification state as appropriate. On token refresh, update the server record. When a provider reports a permanently invalid or unregistered token, deactivate it instead of retrying indefinitely.
The registration flow must be designed for both platforms. Apple’s APNs setup guidance describes the required app capability and provider-side configuration. Android and iOS permission behavior also differ by operating-system version; test the versions you support rather than assuming one universal prompt.
Segmentation is often described as a marketing feature, but it is equally important in operational apps.
A dispatch alert may target drivers assigned to a route and on duty. A financial approval may target only authorized approvers for a particular entity. A customer update may need to reach the purchaser but not everyone who can view the account.
Prefer rules based on server-side authorization and current business state. Never rely solely on a mobile app’s self-declared role or a stale audience export for sensitive operational notifications.
For example, a notification decision can be evaluated as:
eligible = active_account AND authorized_for_resource AND opted_in_where_required AND not_suppressed AND within_delivery_window
The actual logic will vary by message category and jurisdiction. A notification to an employee about a critical workflow may be governed differently from promotional outreach to a consumer. Legal and privacy review should define which messages require consent and what controls must be offered.
If a recipient is removed from a job after the event was queued, the worker should re-check critical eligibility immediately before submission. This reduces the risk of leaking information through an obsolete audience snapshot.
Preferences, consent and quiet hours are product features
A binary “notifications on/off” switch is rarely sufficient for a mature app.
Give users understandable categories, such as assignments, account security, order updates, reminders and promotions. Explain what each category does. Where appropriate, let users set quiet hours, channel choices and notification frequency.
Store a preference version, update timestamp and relevant consent evidence. Separate operating-system permission from application-level preferences: the app may have permission to display notifications even though the user has opted out of marketing messages inside the product.
Do not make the initial permission request the first screen a new user sees by default. Explain the value in context, then request system permission at a meaningful moment, following platform rules. If permission is declined, core app functionality should still work unless the use case genuinely depends on a separately agreed notification mechanism.
Quiet hours need a timezone policy. Is the rule based on the user’s current timezone, home timezone or the business location? What happens during daylight-saving changes? Write down the answer rather than hiding it in scheduling code.
Delivery state: distinguish accepted, delivered, displayed and acted upon
A push pipeline has several distinct states:
- Created: the business event produced an eligible notification.
- Queued: a delivery job exists and awaits processing.
- Submitted: the worker sent a request to the provider.
- Accepted: the provider acknowledged the request.
- Rejected or expired: the provider refused the request, or its useful lifetime elapsed.
- Displayed or received: the app or platform reports an observable device-side event, when available.
- Opened: a user interacted with the notification or its destination.
- Action completed: the intended business action actually occurred.
Not every platform exposes every stage reliably. Device receipt and display can be affected by connectivity, permissions, focus modes, battery management and operating-system behavior. Firebase Cloud Messaging delivery documentation explains available reporting mechanisms and their limitations.
A dashboard showing 99% “sent” may only mean that 99% of requests were accepted upstream. It does not establish that 99% of recipients saw the alert. Report denominators and state definitions explicitly.
For executives, the most useful outcome may be “approvals completed within 30 minutes after an eligible alert,” not raw push volume or open rate.
Retries, time-to-live and duplicate protection
Retries are necessary for temporary network errors, provider throttling and intermittent backend failures. They can also create duplicate alerts if the first attempt succeeded but its acknowledgement was lost.
Use exponential backoff with jitter for retryable failures, bounded by a maximum attempt count and the notification’s expiry. Separate transient failures from permanent errors, such as invalid registration tokens or malformed payloads. Send permanently failed jobs to a reviewable dead-letter queue or terminal failure state.
Time-to-live (TTL) should reflect the business meaning of the message. A flash offer that expires at 6 p.m. should not arrive tomorrow morning. A reminder for an appointment that has already started may be worse than no reminder. For superseded state updates, collapse or replace pending messages where supported, while keeping the underlying in-app record correct.
The FCM REST API documents platform-specific fields including Android TTL and collapse behavior. Do not assume that these settings guarantee a specific arrival time or identical behavior on both operating systems.
Idempotency keys should also protect campaign creation and event handling. A repeated order_shipped event should not create two identical notifications merely because a message broker redelivered it.
Priority is not a substitute for urgency design
Most messages should use normal delivery priority. Reserve elevated priority for genuinely time-sensitive, user-visible events, and validate that behavior on real devices.
FCM guidance on Android message priority explains that high-priority messages are intended for urgent, user-facing content and may be deprioritized when misused. An app that marks every marketing promotion “high priority” can undermine its own reliability.
Urgent workflows should define escalation outside the push channel. For example, a job assignment might require an in-app acknowledgement by a deadline. If no acknowledgement arrives, the backend can notify a supervisor or route the task elsewhere. That is a business workflow with deadlines and state transitions, not a promise that a push provider can force a device to display an alert.
Deep links must survive real-world app states
A notification should take the user to the action, not merely open the home screen.
Define destinations using stable resource identifiers and route types. For example, an approval_requested event can point to an approval detail screen keyed by approval_id, not a fragile URL containing a full snapshot of sensitive business data.
Test at least these states: app foregrounded, backgrounded, terminated, user logged out, session expired, resource deleted, authorization revoked, and app version too old for the destination. The client should authenticate and fetch fresh resource state before showing details. If access is unavailable, show a safe fallback with a clear explanation.
Do not put sensitive personal or commercial information in a lock-screen preview unless the product and privacy requirements explicitly permit it. Even a correct deep link can leak data if the visible notification title contains confidential details.
A useful deep-link contract specifies route, required parameters, minimum supported app version, fallback behavior and the event that confirms successful navigation.

Notification content needs versioning and governance
Templates should be managed like product assets, not scattered strings in application code.
Each template needs an identifier, version, owner, supported languages, variable schema, maximum content length and review process. Include a fallback when optional fields are missing. Preview the rendered notification on both iOS and Android, including long names, right-to-left languages where relevant, truncated text and accessibility settings.
Keep payloads small. Prefer opaque IDs and minimal context over embedding full customer records. Validate variables before rendering. Never allow untrusted text to become an unsafe deep-link destination.
For regulated or sensitive workflows, consider a review trail that records which template version and policy decision produced a notification, without retaining more personal information than necessary.
Analytics should connect notification behavior to outcomes
Measure three layers separately.
Engineering health: eligible events, queue age, send attempts, acceptance rate, transient failures, permanent token failures, retry backlog, and time from business event to provider acceptance.
User experience: opt-in rates by platform and onboarding stage, notification frequency per user, dismissals or opens where measurable, deep-link success, and user-reported relevance or annoyance.
Business outcomes: time to acknowledge assignments, order-status support contacts, approval completion, return visits, or other actions that the notification was meant to support.
Do not interpret a high open rate as proof of incremental value. Users may have completed the action without the notification. Use controlled experiments where feasible, with holdout groups and a defined primary metric. For operational alerts that cannot ethically be withheld, evaluate process reliability, acknowledgement time and exception handling rather than conducting a blanket no-alert experiment.
Segment metrics by notification type, platform, app version and permission state. A blended metric can hide a serious issue affecting one platform or release.
An illustrative example: a field-service assignment
Consider a hypothetical service business that assigns technicians to urgent repairs. The goal is not “send a push when a job is created.” The goal is “make sure an eligible technician can accept or reject a new assignment promptly.”
The dispatch system creates the job and assignment transactionally. An outbox event schedules an alert. The notification service verifies the technician’s current assignment and notification preferences, then sends a short message with a link to the job details. The app fetches the latest job state before allowing acceptance.
If the technician is offline, the job remains visible in the task list. If the alert expires, the backend does not keep resending obsolete instructions. If there is no acknowledgement by a defined deadline, dispatch receives an exception and can reassign the work.
The dashboard reports event-to-acceptance time, unacknowledged assignments, reassignment frequency and push delivery health. It does not confuse an accepted push request with an accepted job.
This is an illustrative design scenario, not a claim about a specific client implementation.
How to choose between a managed platform and a custom orchestration layer
FCM and APNs provide essential device delivery infrastructure. They do not, by themselves, define your business-specific segmentation, authorization, consent evidence, escalation or audit requirements.
A managed engagement platform can accelerate campaigns, templates, audience management and experimentation. It may be appropriate when marketing operations dominate and the team values a ready-made interface. Evaluate its data residency, pricing model, integration options, event semantics, access controls and exportability.
A custom orchestration layer may be justified when notifications are tightly coupled to operational workflows, permissions, complex multi-tenant data or a specific audit trail. It creates additional maintenance responsibilities, including provider changes, queues, observability and on-call support.
Many products use a hybrid: business events and policy checks remain in the application’s backend, while a provider handles device delivery and selected campaign operations. The decision should follow the business requirements, not a preference for building everything from scratch.
Actiknow’s custom solutions and integration work includes web and mobile applications, APIs and workflow automation, which are relevant when notifications must coordinate several business systems.
A practical requirements checklist before development
Ask the product owner and engineering lead to agree on the following decisions before implementation:
- Which business events trigger notifications, and who owns their definitions?
- Which categories are critical, transactional, optional or promotional?
- What is the source of truth when the push is delayed or missed?
- How is the recipient authorized at event time and again at send time?
- How do token registration, rotation, logout and invalidation work?
- What preference, consent, quiet-hour and retention rules apply?
- What are the TTL, collapse, retry and deduplication policies?
- What should happen if the recipient has no permission or no network?
- What screen opens from each notification, and what are the safe fallbacks?
- Which events prove technical delivery, engagement and actual task completion?
- Who investigates failures, and how quickly must urgent incidents be escalated?
- What operational load and vendor cost should the design support?
A team that cannot answer these questions is not ready to estimate the full notification feature confidently. A provider SDK integration is only one line item.
A four-week implementation and validation plan
Week 1: define events, policy and user journeys
Inventory all proposed notifications. Rank them by business criticality. Agree on event schemas, user and device identity, authorization checks, consent requirements, preference categories and measurable outcomes. Design notification destinations and fallback states. Document what happens if push never arrives.
Week 2: build the reliable delivery path
Implement event persistence, a durable queue or outbox as appropriate, template rendering, recipient resolution, token lifecycle management and provider integration. Add idempotency keys, expiry rules, bounded retries and structured logging. Keep sensitive content out of unnecessary logs.
Week 3: integrate mobile behavior and observability
Implement foreground and background handling, permission prompts, deep links, authentication recovery and in-app fallbacks. Instrument the event-to-action journey. Create operational views for queue backlog, provider failures, token invalidation and notification latency.
Week 4: test failure modes and launch gradually
Test real devices, operating-system versions, offline transitions, duplicate events, expired jobs, revoked permissions, logout, multiple devices, app upgrades and provider throttling. Roll out to a limited audience, review complaint signals and measure the intended workflow outcome. Set alert thresholds and assign an operational owner before expanding.
Four weeks is an illustrative planning sequence for a focused capability, not a universal delivery commitment. Scope, compliance requirements and existing infrastructure can change the timeline substantially.
Operational controls that matter after launch
A production system needs more than a delivery graph. Set alerts for a growing queue, sustained provider rejections, a sudden spike in invalid tokens, unusual campaign volume and time-sensitive events approaching expiry.
Provide a controlled way to pause a campaign, disable a template or suppress a faulty event type. For high-volume sends, use rate limits and batching that respect provider guidance and protect your own backend. Separate development, staging and production credentials and audiences so tests cannot accidentally notify customers.
Review notification taxonomy and preferences periodically. As products evolve, teams often add new alert types without reconsidering frequency or consent. The resulting noise can make the most important messages easier to ignore.

Common mistakes to avoid
Treating provider acceptance as guaranteed device delivery. Sending before the business transaction is committed. Storing only one token per user. Retrying expired alerts. Sending sensitive information to lock screens. Using high priority for every message. Ignoring permission declines. Linking to screens that fail after logout. Measuring opens without measuring completed actions. Letting every department send to the same users without shared frequency controls.
The shared theme is simple: a notification system needs product rules, durable data and operational ownership, not only a mobile SDK.
Frequently asked questions
1. Do we need both FCM and APNs?
Android delivery commonly uses FCM. iOS delivery ultimately relies on APNs, even when a team uses FCM as a unified integration layer. Your exact architecture depends on the SDK, provider and app configuration. Test both platforms independently.
2. Can push notifications guarantee that a user sees an urgent message?
No. Device connectivity, operating-system controls, permissions and user behavior limit that guarantee. Critical processes should use durable in-app state, acknowledgement deadlines and suitable escalation channels.
3. Should notification preferences live in the app or backend?
The app should provide a clear interface, but server-side preferences should be authoritative for message eligibility across devices. Operating-system permission is a separate control that the backend may not observe perfectly.
4. What happens when a user logs in on two phones?
Model installations and tokens independently. Decide whether the event should notify all eligible devices or only selected ones. Keep business actions idempotent so two notification taps cannot complete an approval twice.
5. How do we avoid duplicate notifications?
Deduplicate event handling with stable IDs, use idempotent notification creation and protect delivery workers against retries. Device-level duplicate display can still require careful platform-specific handling.
6. What should we do when a device is offline?
Keep the business item available through the app’s normal data retrieval or sync process. Set a TTL that matches the event’s usefulness, and never depend on eventual push delivery to create the underlying task.
7. Are deep links safe for confidential workflows?
They can be, if the app authenticates the user and re-checks authorization against current server state. Do not treat possession of a notification link as permission to access the underlying resource.
8. Which metric should a product leader review first?
Choose the outcome the notification exists to improve, such as time to approve a request or proportion of assignments acknowledged on time. Use delivery and interaction metrics to diagnose why that outcome changes.
9. When is a third-party engagement platform worth paying for?
It can be useful when campaign management, experimentation, localization and marketing operations are substantial. Compare those benefits with integration, privacy, licensing and data portability requirements.
10. What is the minimum viable push architecture?
For a simple, low-risk app: trustworthy event creation, user/device token registration, category preferences, a durable send queue, bounded retries, deep-link handling and basic operational metrics. Add more sophisticated orchestration as business criticality grows.
The decision for product leaders
Reliable push notifications are a small visible feature supported by a much larger invisible system. The value comes from delivering timely, relevant prompts without making the business process dependent on a device or a provider.
Start with the user action and the cost of a missed message. Design the event, recipient policy, delivery lifetime, fallback and outcome measurement around that decision. Then select the SDKs, vendors and infrastructure that fit.
If you are planning a mobile product or improving an existing notification workflow, contact Actiknow to discuss the application architecture, integrations and operational requirements. A useful first conversation is a review of your event types, recipient rules and failure scenarios, not a promise about notification open rates.
Technical references
Firebase Cloud Messaging delivery documentation explains the difference between upstream acceptance and observable downstream delivery reporting.
FCM guidance on Android message priority describes the trade-offs around normal and high-priority delivery.
Apple’s APNs setup guidance covers the app capability and provider configuration needed for iOS notifications.
The FCM REST API reference documents message fields such as TTL and collapse settings.

