Architecture · October 27, 2026 · Daniel Murillo
How push notifications work: VAPID, FCM, APNs, and cross-platform
Push is not a direct connection to the phone. Tokens, topics, VAPID, FCM, APNs, Web Push, and what changes with Capacitor, React Native, or Flutter.
A push notification is not sent directly from your backend to the phone. Your system identifies an installation or an audience; a platform push service routes the message to the operating system or browser, which decides how to present it and when to wake the application.
Introduction: it looks like a message, but it is a chain of systems
When an application shows “You have a new message,” it can seem as if the backend opened a connection to the phone and sent it text. In reality, the mechanism is usually different.
Your application backend decides there is something to notify. It sends a request to a push provider, such as Firebase Cloud Messaging (FCM), Apple Push Notification service (APNs), or the browser’s push service. That provider maintains or manages the delivery infrastructure toward devices. The operating system or browser receives the message and, depending on its content and the application state, can show a notification, deliver data to the app, or run an allowed handler.
This means the backend does not have to keep its own WebSocket connection to every phone just to notify it when inactive.
This article walks through the full process: how a device is registered, what tokens are, what VAPID means, how topics work, what differences exist between iOS and Android, and what changes when developing with web, Capacitor, Cordova, React Native, or Flutter.
1. Push, local notification, and real-time messaging are not the same
Before talking about providers, it helps to distinguish three mechanisms.
Local notification
The application schedules or generates the notification on the device itself. For example, a reminder for two hours from now. It does not need your backend to send a message at that moment, although the application may have previously obtained the data.
Remote push notification
Your backend asks the push provider to deliver a message to an installation or an audience. The provider handles the route to the device. The application may not be open.
Real-time messaging
A WebSocket or similar connection keeps a communication channel between the client and a server while the connection is active. It is useful for chat, presence, and interactive updates. It does not by itself replace push when the app is suspended or the operating system has closed its process.
An architecture can combine both mechanisms: WebSocket while the app is active and push to announce important events when it is in the background.
2. The general architecture of a push notification
Business event in the backend
|
v
Notification service
|
v
Resolve recipients
| |
v v
Token / installation Topic / segment
| |
+------+-------+
|
v
FCM / APNs / Web Push
|
v
Operating system or browser
|
v
Visible notification / callback / service worker
|
v
Deep link or in-app navigation
The main components are:
- Business backend: detects an event, such as a new message, a purchase, or a reminder.
- Notification service: decides whom to notify, builds the payload, and applies preferences, priorities, and rules.
- Installation registry: relates user accounts to tokens or subscriptions for each installation.
- Push provider: FCM, APNs, Web Push, or another layer that integrates with platform services.
- Operating system or browser: receives, presents, and routes the interaction.
- Application: interprets the data and opens the appropriate screen when needed.
Apple describes an equivalent chain for remote notifications: provider server, APNs, device, and application. APNs manages the connection infrastructure toward the device; the application server does not need to hold a direct connection to every phone.
Source: Apple — Setting up a remote notification server
3. How is a device registered?
To send a targeted push, your system needs an identifier that the provider can route.
A typical flow is:
- The user installs or opens the application, or enters a compatible web site.
- The application explains the value of notifications and requests permission when appropriate.
- The SDK or platform registers that installation with the provider.
- The provider returns a token or a subscription.
- The application sends that identifier to your authenticated backend.
- Your backend stores it and relates it to the user, platform, and installation.
- When an event occurs, the backend queries the registry and sends the push to the correct recipient.
On Apple, the APNs token identifies a combination of application and device: two apps installed on the same iPhone do not share the same token. In FCM, the registration token is used to direct messages to a registered instance of the application. In Web Push, the client stores a subscription that includes an endpoint and encryption keys.
The token is not the user ID
Do not design the database assuming each user has a single token. A person can have:
- an iPhone and a tablet;
- a personal phone and a work phone;
- an installed app and a subscribed PWA;
- several installations after reinstalling;
- sessions of the same account on different devices.
That is why a registry table can have one row per installation or push destination, not only a push_token column on users.
| Field | What it is for |
|---|---|
id | Internal registry ID |
user_id | Account it belongs to, if there is a session |
platform | ios, android, web |
provider | apns, fcm, webpush, etc. |
token or subscription | Push address/token; protect and limit access |
installation_id | Internal installation ID |
app_version | Diagnosis and compatibility |
last_seen_at | Last known activity |
enabled | Preference or registration state |
created_at, updated_at | Registry lifecycle |
In Web Push, the subscription includes an endpoint and cryptographic material; it should not be treated as exactly the same type of token as FCM or APNs.
Tokens change
Tokens and subscriptions can rotate, invalidate, or stop being valid after reinstalling, restoring, changing settings, or revoking permissions. The app must update the registry on the backend when it receives a new token, and the server must remove destinations the provider reports as invalid.
Do not use the token as a user password or as sufficient proof of identity. It must be registered through an authenticated endpoint, the relationship with the account must be validated, and a person must not be able to arbitrarily associate someone else’s token.
4. How does the provider know which device to send the notification to?
This is the key question: how does a notification reach a single device and not everyone?
Because the backend does not simply send “a notification for the application.” It sends a message with a concrete destination.
Direct send to a token
Suppose an account is signed in on three installations:
- the person’s iPhone: token
token-A - the person’s Android: token
token-B - laptop browser: subscription
subscription-C
If the backend sends the message to token-A, the provider tries to deliver it to that installation associated with token A. It does not automatically route it to token B or subscription C.
If you want the person to receive the alert on all their devices, the backend must send the message to each active destination, or use a provider abstraction that manages that list. The provider does not guess which devices belong to the same person: your system must maintain that relationship.
The identifier does not always represent a physical phone
A token normally identifies an application or installation destination on a platform, not necessarily unique hardware. Exact semantics depend on the provider.
- APNs: token associated with the app and the device.
- FCM: registration token for an app instance.
- Web Push: subscription of a service worker for a site/origin and browser.
- An intermediary provider can create its own installation ID or endpoint and keep the platform token behind it.
What if the user has several sessions?
Define a product policy:
- send to all active installations;
- send only to the installation that started the action;
- exclude the current device;
- send to all devices except those that already received or read the event;
- group or silence duplicate messages.
It is not an automatic decision of the push system. It is logic in your backend.
5. Topics, tokens, and groups: three different strategies
The word topic is used in several systems and does not always mean the same thing.
Individual recipient: token
Used when you know exactly which installation you want to send the message to.
Examples:
- “Your order was shipped” to the account’s installations.
- “You have a new message” to a concrete user.
- “A sign-in started on your account” to their registered devices.
FCM topic
An FCM topic is an audience that application instances subscribe to. The backend publishes to that topic and FCM distributes the message to subscribed registrations.
Examples: product_updates, team_42_announcements, weather_city_abc.
Topics are for broadcasts and broad audiences. They are not ideal for private or highly personalized information. If a notification contains confidential information, do not send it to a public or overly broad topic.
Source: Firebase — Topic messaging
A broker topic, such as Google Cloud Pub/Sub
A Google Cloud Pub/Sub topic distributes events among backend services and processing subscriptions. It is not the same as an FCM topic aimed at mobile installations.
Order updated
|
v
Google Cloud Pub/Sub: orders-events
|
v
Notification worker
|
+--> Looks up the user and their installations
|
+--> Sends to FCM / APNs / Web Push
Pub/Sub decouples producers and consumers in the backend; FCM or APNs handle the last mile to devices. Google Cloud expressly states that Pub/Sub is oriented toward service-to-service communication, while FCM is a more appropriate option for delivering messages to web and mobile applications.
Your own topics in the application
You can also keep segments in your database: for example, all users who follow an artist. Your backend resolves that audience to a list of tokens and sends in batches. In this case, “topic” is a domain abstraction of yours, not necessarily an FCM topic.
6. VAPID: what it is and when it is used
VAPID means Voluntary Application Server Identification. It is a mechanism for identifying/authenticating the application server in the Web Push protocol.
In Web Push, the browser or push system provides a subscription that contains an endpoint and encryption keys. Your application server generates an encrypted message and sends it to that endpoint. VAPID lets the server identify itself to the push service using a key pair: public and private.
What VAPID does
- Identifies the application server to the push service.
- Uses a public key provided when creating the subscription.
- Signs an authorization token with the private key.
- Helps the push service relate a subscription to the server authorized to send it messages.
What VAPID does not do
- It is not the device token.
- It is not the notification content.
- It is not a topic.
- It does not replace Web Push payload encryption.
- It is not the credential a native app uses to authenticate directly against APNs.
- It is not required for every native notification path with FCM/APNs.
In web applications, the VAPID public key is used in the subscription flow; the private key must stay on the backend and never be included in the frontend.
Apple documents VAPID as part of preparing the server for Web Push. It also specifies that you build and encrypt the payload and send it to the subscription endpoint URL.
Source: Apple — Sending web push notifications
Simplified Web Push flow
- The user accepts notifications.
- The browser registers a service worker.
- The browser creates a
PushSubscription, using the VAPID public key when appropriate. - The frontend sends the subscription to the backend.
- The backend stores the endpoint and subscription keys.
- When an event occurs, the backend encrypts the payload and signs the request with VAPID.
- It sends the request to the push service endpoint.
- The browser receives the
pushevent in the service worker and can show a notification.
const registration = await navigator.serviceWorker.register("/sw.js");
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: PUBLIC_VAPID_KEY,
});
await fetch("/api/push-subscriptions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(subscription),
});
The public key can be on the client; the private one never. The backend should use a maintained Web Push library for encryption, format, and signing, instead of implementing the protocol manually.
7. Google FCM and Apple APNs: what each one does
Firebase Cloud Messaging (FCM)
FCM is Google’s service for sending messages to application instances. It integrates especially with Android and can also participate in iOS and Web Push flows. To send messages from a server you normally use the HTTP v1 API or the Admin SDK, with server credentials.
FCM can address messages to:
- a registration token;
- a topic;
- a condition based on topics.
The payload can contain a notification section, custom data, or both. Behavior depends on the platform and the application state.
Source: Firebase — Send a message using FCM HTTP v1
Apple Push Notification service (APNs)
APNs is Apple’s infrastructure for remote notifications on its platforms. The provider server authenticates with APNs, for example with a provider token signed with an authentication key or via certificates depending on configuration. APNs routes the message to the device.
The application server does not need to keep a direct connection to every iPhone. APNs manages delivery connections and can temporarily store notifications for offline devices, subject to the service’s policies and limits.
Does FCM replace APNs on iOS?
Not exactly. In an iOS app that uses Firebase Cloud Messaging, FCM can provide a unified API for the backend, but registration and delivery in the Apple ecosystem still involve APNs. The app must be configured with the capabilities and credentials required for the platform.
In other words, FCM can be a common layer for your backend, but it does not remove Apple’s rules or make APNs disappear from the iOS delivery path.
8. What happens on Android, iOS, and browsers?
Native Android
The application registers with FCM and obtains a token. Your backend stores it and sends messages via FCM. The Android system manages notification presentation according to the payload, notification channel, permissions, and app state.
Since Android 13, applications must request the POST_NOTIFICATIONS runtime permission to show non-exempt notifications. That FCM accepts a message does not mean the user will see an alert if the permission is denied or system settings block it.
Source: Android Developers — Notification runtime permission
Native iOS
The app requests authorization from the user, registers with APNs, and receives a device token. That token is sent to the backend. The server sends the payload to APNs, which routes it to the device.
User authorization, system settings, Focus mode, scheduled summary, connectivity, and system policies can affect presentation. The server cannot force a notification to appear as a banner in every context.
Source: Apple — User Notifications
Web and PWA
The web uses the Push API and a service worker. The subscription contains an endpoint and cryptographic keys; the backend uses Web Push and VAPID to send the payload to the browser’s push service.
Capabilities vary by browser, operating system, PWA installation, and permissions. Do not assume the same behavior in Chrome for Android, Safari on macOS, and Safari on iPhone.
On iOS/iPadOS 16.4+, Web Push only works for sites added to the Home Screen and opened as a web app. In a normal Safari tab, Notification may not exist and you will not be able to subscribe the user. The permission request must happen in response to a gesture (for example, a tap on “Enable notifications”). If you show a subscribe button that cannot work in a tab, you are breaking the experience.
Safari requires a visible notification: the service worker must call showNotification when receiving the push event. If you do not show a notification, Safari may revoke the subscription. Do not use “silent” push as a general background wake mechanism.
Since iOS/iPadOS 18.4+, WebKit documents Declarative Web Push: a message format the browser can show even if the service worker handler fails (or without depending on it as much). It is an option to evaluate when you want more resilience in Safari; it remains compatible with the standard Web Push flow in other browsers if you design with feature detection.
Sources:
- Apple — Sending web push notifications
- WebKit — Web Push for Web Apps on iOS and iPadOS
- WebKit — Meet Declarative Web Push
9. Native, Capacitor, Cordova, React Native, and Flutter
A cross-platform app does not remove push differences between systems. It normally offers a common API or plugin that connects shared code with native SDKs. The plugin simplifies the work, but credentials, capabilities, permissions, entitlements, and operating-system restrictions still exist.
| Technology | How push is usually implemented | Considerations |
|---|---|---|
| Native Android | FCM SDK and Android APIs | FCM token, permissions, channels, and native callbacks |
| Native iOS | APNs and UserNotifications; optionally FCM as a common layer | Capability, entitlements, APNs token, and authorization |
| Web/PWA | Push API, service worker, and Web Push/VAPID or FCM web integration | Subscription, permissions, browser compatibility, and installation context |
| Capacitor | Plugin that bridges JavaScript with native capabilities | Android uses FCM; iOS requires Push Notifications/APNs configuration |
| Cordova | Native plugin, for example a plugin that integrates Firebase | Plugin status and maintenance matter; review compatibility with current versions |
| React Native | Community libraries that integrate FCM/APNs and native modules | The React Native API does not remove native configuration; choose maintained libraries |
| Flutter | Plugins such as Firebase Messaging that connect Dart with native SDKs | Firebase, APNs, and permission configuration per platform |
Capacitor
The official @capacitor/push-notifications plugin offers an API to register the device, receive events, and handle interactions. Its documentation states that Android uses Firebase Cloud Messaging and that on iOS you must enable the Push Notifications capability and configure the required native bridge.
Source: Capacitor — Push Notifications
Cordova
Cordova depends on plugins to expose native APIs to JavaScript. Installing any push plugin is not enough: review recent activity, support for current Android/iOS versions, Xcode requirements, Firebase configuration, and compatibility with your Cordova version. An abandoned plugin can block an operating-system update.
React Native
React Native’s own older PushNotificationIOS API is marked deprecated; the documentation recommends using community packages. A common option is React Native Firebase Messaging, but you must review compatibility with the React Native version and native configuration instructions.
Flutter
Flutter uses plugins that connect Dart code with native SDKs. Firebase Messaging is a frequent option for FCM and notification flows on iOS/Android. You still need to configure native projects, permissions, credentials, and foreground/background behavior.
Source: Firebase — Flutter Cloud Messaging
The real difference
The framework changes how you write client code and how you configure the native bridge. It does not change the fundamental delivery rules: you need to register each installation, store its destination, request permissions, and handle app states.
10. What parts does a notification have?
A notification can combine visible information and data the app processes.
Visible content
- Title.
- Text or body.
- Icon or image, depending on the platform.
- Sound.
- Badge or counter.
- Priority or interruption level.
- Category/channel.
- Actions, according to platform capabilities.
Custom data
{
"type": "chat.message",
"conversationId": "conv_123",
"messageId": "msg_456",
"route": "/chat/conv_123"
}
This object represents data so the application knows which resource to open. It is better not to include unnecessary private information in the payload: the screen can fetch the full content from your API after authenticating the user.
FCM distinguishes between notification messages and data messages. Behavior changes by Android/iOS, foreground/background, and client implementation. Do not assume a data payload will always run immediately if the app is suspended.
Source: Firebase — Message types
Do not use push as the source of truth
A push can be delayed, grouped, expire, or not be shown. The database and API remain the source of truth. The message should work as a signal: “there is something to fetch,” not as the only copy of a critical event.
11. Actions: what happens when the user taps a notification
A notification can have a default action (open the app) or specific buttons, for example:
- Open conversation.
- Mark as read.
- Accept or decline an invitation.
- Reply quickly.
- Open an order or a reservation.
- Dismiss or snooze a reminder.
The operating system lets you define categories or actions, but support and experience depend on the platform and framework. Some actions can run without opening the full interface; others open the app to complete the operation.
Deep links
The payload can include an identifier or a logical route, for example conversationId. When the user taps the notification:
- The system opens or brings the app to the foreground.
- The plugin delivers the interaction event.
- The app obtains the destination and validates authentication state.
- The app navigates to the corresponding screen.
- The screen loads current data from the API.
Do not trust a received route as if it were authorization. The backend must validate that the user can access the resource. If the user signed out, show the authentication flow and resume navigation only after validating permissions.
Foreground, background, and terminated
There are at least three states you must test:
- Foreground: the app is visible. The system may not automatically show a banner; the app can decide to show its own UI or present the notification.
- Background: the app is not visible, but the system can manage the message and show it.
- Terminated: the process is not active. On tapping the notification, the app starts and must recover the initial notification or launch intent according to the framework.
Silent or data-message behavior in the background is subject to operating-system restrictions and must not be treated as guaranteed execution.
12. Which cloud services can I use?
There are two different categories: providers that deliver push to devices, and messaging services that connect components of your backend.
Push providers
| Service | What it provides | When to consider it |
|---|---|---|
| Firebase Cloud Messaging (FCM) | Send to tokens, topics, and conditions; Android and web integration, and an integration layer with APNs for iOS | Good multiplatform starting point |
| Apple APNs | Native remote delivery on Apple platforms | Required on the native iOS path, directly or behind a provider |
| Amazon SNS Mobile Push | Platform endpoint abstraction and send to FCM/APNs and other supported services | If infrastructure already lives on AWS or SNS topic segmentation is required |
| Azure Notification Hubs | Installation/tag management and cross-platform sends to PNS | If Azure is already used or device segmentation and administration are needed |
| OneSignal | Managed platform with segmentation, campaigns, analytics, and platform provider integration | If you need more than a send API, such as campaigns and audience management |
| Expo Push Service | Send layer for Expo/React Native applications according to its configuration | If the project uses Expo and the service covers its requirements |
Messaging services for the backend
| Service | Role | Do not confuse with |
|---|---|---|
| Google Cloud Pub/Sub | Asynchronous events between services and workers | Not by itself the push service to the mobile |
| AWS SNS | Can distribute messages to endpoints and also integrates mobile push | Not the same as SQS |
| AWS SQS | Job queue to process sends asynchronously | Does not directly deliver a notification to the OS |
| Azure Service Bus | Queues and topics for backend communication | Does not replace APNs/FCM |
| RabbitMQ / Kafka | Events or queues within your architecture | Require a worker that resolves recipients and calls the push provider |
| Cloud Tasks | Asynchronous, controlled execution of HTTP tasks | Not the provider that delivers push to the phone |
Google Cloud Pub/Sub separates producers and consumers and is oriented toward service-to-service communication. FCM, by contrast, provides destinations for client applications. They can be used together: Pub/Sub receives business events and a worker consumes those events, resolves users and tokens, and calls FCM/APNs.
Suggested cloud architecture
Business API
|
v
Event: order.shipped
|
v
Backend queue or topic (optional)
|
v
Notification worker
|
+--> Queries preferences and users
+--> Resolves active installations
+--> Builds payload per platform
+--> Sends to FCM / APNs / Web Push
+--> Stores result and retries
You do not need a broker from day one. A small application can send directly from a backend service with a persistent queue for retries if reliability requires it. A broker becomes useful when you want to decouple events, absorb spikes, retry, and scale workers independently.
13. What do “sent,” “delivered,” and “seen” mean?
They are not the same state.
- Accepted by the provider: the API accepted the request; it does not mean the phone already showed it.
- Delivered to the device or transport: signals or metrics may be available, but exact confirmation does not always exist for every platform and message type.
- Shown by the system: the OS presented the notification, if the message and permissions allowed it.
- Opened by the user: the person tapped the notification or ran an action.
- Processed by the app: the application completed an operation, such as marking the message as read.
FCM offers aggregated delivery metrics for certain scenarios and Android; not all paths provide an identical individual confirmation. APNs can accept a request without guaranteeing that the user has seen the notification.
For important events, record your own business states and the interactions the client can confirm. Do not promise “exactly-once delivery” based only on the push API.
Source: Firebase — Understanding message delivery
14. Retries, duplicates, expiration, and order
Push delivery is asynchronous and subject to networks, system policies, and device states. Design the backend assuming there can be delays, stale messages, or retries.
Good practices:
- Assign a unique
notification_idorevent_id. - Make action processing idempotent.
- Define TTL so an old notification does not appear after it no longer makes sense.
- Use collapse keys or equivalent mechanisms only when it is appropriate to group replaceable messages.
- Remove invalid tokens.
- Do not retry permanent errors indefinitely.
- Record response codes and failure cause.
- Keep a notification inbox on the backend if the experience requires reliable history.
- On opening the app, sync real state from the API.
For example, if a user receives ten “order in preparation” updates, it may be enough to show the most recent state. By contrast, do not collapse ten financial events that the product needs to record individually.
15. Security and privacy
Tokens and subscriptions are operationally sensitive identifiers. Do not expose them in public logs or accept them without validation.
- Store FCM server credentials, VAPID private keys, and APNs credentials only on the backend or in a secrets manager.
- Never include private credentials in the frontend, APK, or JavaScript bundle.
- Register tokens through an authenticated session and verify which account they belong to.
- Disassociate installations on sign-out when required by the privacy policy.
- Avoid sending secrets, financial data, or full private content in visible payloads.
- Validate permissions when opening a deep link.
- Allow disabling notifications by category and respect user preferences.
- Delete invalid destinations and set a registry retention policy.
Web Push transport and payload encryption do not replace authorization of the resource the notification invites the user to navigate to.
16. Common mistakes
- Storing a single token per user. An account can have multiple installations.
- Trying Web Push in a Safari iOS tab. On iPhone/iPad you need the web app on the Home Screen; request permission only there, after a gesture.
- Confusing VAPID with FCM or APNs. VAPID belongs to the Web Push flow; it does not replace native APNs credentials.
- Thinking a Pub/Sub topic is an FCM topic. One connects backend services; the other directs messages to an audience of registered apps.
- Believing HTTP 200 means the user saw the notification. It usually only indicates acceptance of the request at that stage.
- Sending private data to broad topics. Topics are for audiences, not for confidential individual information.
- Not updating tokens. Installations change and tokens can invalidate.
- Testing only with the app open. Foreground, background, and terminated behave differently.
- Assuming a cross-platform plugin removes native configuration. Certificates, capabilities, permissions, and SDKs still exist.
- Using push as reliable storage. The source of truth must be on the backend.
- Not handling the tap/deep link. The notification appears, but the app does not know which screen to navigate to.
- Omitting
showNotificationin Safari. If the service worker does not show a visible notification, the subscription may be revoked.
17. Architecture recommendation
For a new cross-platform application, a reasonable initial architecture could be:
- A backend notification service decoupled from business logic.
- An installations/destinations table, with multiple records per user.
- FCM as a starting point for Android and, if convenient, as a unified send layer; APNs configuration for iOS.
- Web Push with service worker and VAPID for a PWA, or Firebase Messaging Web if its features fit.
- An adapter per provider (
FCM,APNs,WebPush) behind your own interface if you need to change or combine providers. - A queue such as SQS, Pub/Sub, or Service Bus when you need retries, spike absorption, or independent processing.
- Small payloads with resource IDs and logical routes.
- Deep links validated by the application and authorization on the backend.
- Metrics for acceptance, failures, invalid tokens, and opens.
- Tests for foreground, background, terminated, denied permissions, and rotated tokens.
Do not start by building a huge abstraction that supports ten providers if you only need one. Encapsulate what actually varies: destination registration, sending, errors, TTL, per-platform data, and telemetry.
Conclusion
A push notification is not a direct connection from the backend to the phone. It is a message routed by infrastructure that knows the registered destination of an application or subscription.
For it to reach a single device, the backend sends to that installation’s specific token or endpoint. For it to reach all of a person’s devices, it maintains the relationship between user and installations and sends to each active destination. For a broad audience, it can use provider topics or resolve a segment in its own backend.
VAPID identifies the server in Web Push; FCM offers a messaging layer for applications; APNs manages Apple’s remote delivery; and frameworks such as Capacitor, Cordova, React Native, and Flutter simplify client code without removing native rules.
Your backend decides who should receive the message; the push provider routes the message; the operating system decides how to present it; and the application validates what should happen when the user interacts.
Related reading
- WebSockets, SSE, and Webhooks
- Optimizing REST APIs
- Tool: which API protocol fits you
- Tool: which backend fits you
References
Apple and Web Push
- Apple — Setting up a remote notification server
- Apple — Registering your app with APNs
- Apple — Token-based connection to APNs
- Apple — Sending web push notifications
- WebKit — Web Push for Web Apps on iOS and iPadOS
- WebKit — Meet Declarative Web Push
- MDN — Push API
Google and FCM
- Firebase — FCM HTTP v1 API
- Firebase — Topic messaging
- Firebase — Message types
- Firebase — Understanding delivery
- Google Cloud Pub/Sub overview
Frameworks and cloud providers
- Capacitor — Push Notifications
- React Native — PushNotificationIOS (deprecated)
- React Native Firebase — Messaging
- Firebase — Flutter Cloud Messaging
- Amazon SNS Mobile Push
- Azure Notification Hubs
- OneSignal — Push notifications
- Expo — Push notifications
- Android — Notification runtime permission
Push capabilities and APIs change by OS version, browser, SDK, and plugin. Before implementing, validate the documentation of the chosen platform. Code examples in this article are illustrative and do not include a complete authentication system.