Where to start
The campaign dashboard says sending is complete, yet the test phone shows nothing. Developers report a normal server response; operations reports that customers received no notification. First establish which stage that screen's “success” actually represents, rather than checking the send count.
OneSignal Delivered means a push provider such as FCM or APNs accepted the message. An FCM message ID likewise indicates acceptance of the delivery request, not proof that the phone displayed it. A successful server response and a customer's missing-notification report can therefore both be correct.[1][3]
To narrow the cause, separate request acceptance → audience selection/queue → push-provider acceptance → device receipt → display → reading/interaction. Do not infer a later stage from an earlier success; move forward from the last verified evidence. The diagnostic sequence and record template below are an operational design applying that principle.
Six stages of success lead to different investigation owners
The first stage is sending API request acceptance: verify the intended project/app, errors in the response body and a trackable message ID. Next is audience selection and queuing. Device settings are not the first concern if the scheduled time has not arrived, no valid recipients exist or limits excluded them. OneSignal distinguishes states such as Scheduled, Queued and No Recipients, with targeting, scheduling and limits in message settings.[1]
At push-provider acceptance, FCM/APNs responses and errors become relevant. Confirm device receipt through SDK records or supported acknowledgments. For display, separately observe notification center, lock screen or banners. Finally, distinguish a notification click from an app launch when recording reading/interaction. Click metrics cannot prove whether someone understood a banner they read without clicking.[1][2]
These six stages are a logical diagnostic model. They do not imply every service exposes six events, uses the same ID at each stage or retains end-to-end records for every message. Apple's Push Notifications Console provides APNs delivery logs, but those are not equivalent to display or reading confirmations.[14]
Classify each stage as verified / not yet verified / unobservable in this environment. Compressing all three into success/failure easily mistakes missing instrumentation for an incident.
From channel setup to campaigns and handover — Connect the SDK and channels, verify key campaigns and hand over an operating setup the internal team can continue.
OneSignal Delivered and Confirmed receipt establish different facts
| Dashboard metric | What it establishes | What it does not establish alone |
|---|---|---|
Sent | Send count including successful and failed transmissions to the provider | Successful transmission or device-receipt counts |
Delivered | Delivery/acceptance at the push provider | Device arrival or display |
Confirmed receipt | Device-receipt acknowledgment from the OneSignal SDK | Banner display or whether a person read it |
Clicked | Subscriptions that clicked the notification | Nonreceipt on devices that did not click |
These definitions apply to OneSignal push reports. Do not combine similarly named metrics in other products as though they share the same meaning.[1][2]
Official documentation currently calls the feature Confirmed receipt, also known as Confirmed Delivery. It requires a paid plan and the device's OneSignal SDK, and does not support API-only Subscriptions. iOS needs a Notification Service Extension and App Group configuration, with mutable-content: 1 in the push. Safari does not support this receipt-confirmation feature.[2]
When confirmation is missing, investigate whether the acknowledgment path is configured, as well as actual delivery. Incorrect iOS extension or App Group configuration can prevent acknowledgment even when the device receives push. Conversely, receipt confirmation can exist while app code or display policy prevents a visible notification.[2]
Narrow the first check by symptom
Even “nobody receives it” needs a defined scope: two internal test devices, or the verified entire audience of a campaign? The following diagnostic design connects official troubleshooting documentation with the platform conditions discussed later. The first check specifies investigation order, not a confirmed cause.[13]
| Symptom | First check | Required evidence | Next action | Observation limit |
|---|---|---|---|---|
| None of the checked recipients see it | Correct app/project; actual audience; schedule/queue state | Request/message IDs, targeting conditions, send time and provider errors | Fix targeting if empty; check credentials/app environment for acceptance errors | Campaign totals do not reveal individual device state |
| Only iOS fails to display | APNs acceptance and matching app/environment identity | iOS recipient records, APNs errors, app build, permissions and Focus | After acceptance, inspect receipt/foreground handling; check NSE/App Group if only acknowledgment is missing | Android success does not validate iOS integration |
| Only Android fails to display | Notification permission and the channel actually used | OS/target SDK, permission state, channel ID/importance and payload | After display settings, inspect foreground/background behavior and receive handlers | FCM receipt and notification display are different events |
| Only a particular user/device fails | Whether that installation was actually targeted | Member/Subscription mapping, registration update time and device permission | Check for another device or old installation; synchronize registration through the normal path | Current subscription state does not prove its state at sending time |
| Late or intermittent delivery | Separate sending wait from delay after provider acceptance | Scheduled/accepted/received times, network, TTL, priority and collapse settings | Vary queue wait, offline state, expiry or app state one at a time | Clock differences and reporting latency are not automatically delivery latency |
| Receipt is evidenced but no display | Display location and app display handling | Device receipt logs, banner/notification-center observation, foreground state and suppression code | Check display policy/app code before rebuilding delivery integration | Even observed display does not prove actual reading |
For a specific device, check the receiving address before the membership ID
A OneSignal User represents a user; a Subscription is a channel receiving unit such as a device or browser. One person can have several Subscriptions. An existing account does not prove the phone in your hand was targeted. Match the targeted Subscription to the current installation and check last synchronization and subscription state.[4]
With direct FCM integration, compare the client's registration identifier, server-stored value and update time according to the registration mechanism in use. Token-based implementations follow the same principle. Handle invalid-registration responses such as UNREGISTERED, but do not immediately delete a token after INVALID_ARGUMENT: malformed payloads can produce the same error, so validate the payload first.[5]
The OneSignal identity and event specification kit provides a format for member/profile/recipient mappings. Here it helps identify the installation targeted by the problematic message, rather than redesigning the complete data model.
Android and iOS require different display checks
Android: inspect permissions, channels, payload and app state together
Android 13 (API 33) and later require runtime notification permission for nonexempt notifications. Newly installed apps have notifications off by default until permission is granted. Do not assume upgraded apps share that state; inspect actual permission.[6]
For apps using notification channels on Android 8.0 (API 26) and later, distinguish app-wide permission from individual channel settings. An app targeting SDK 26 or later cannot display a notification posted without a channel. Even an existing channel may be disabled or have user-modified importance, so match the specified sending channel with the device channel.[7]
Then check message type. FCM notification messages go to the system notification tray in the background but to onMessageReceived in the foreground. data messages depend on app handling. A combined payload displays a notification in the background and delivers its data when the user opens it. Therefore, absence of an onMessageReceived record for a background notification message does not establish nonreceipt.[8]
iOS: separate the APNs path from display policy
FCM messages to iOS also pass through APNs. Beyond the FCM success screen, check APNs configuration/errors, device permission and lock-screen, notification-center and banner settings. Focus controls which apps can notify and when. With an Apple Watch, also determine which device displayed the notification.[9][10]
For foreground display, inspect UNUserNotificationCenterDelegate handling and presentation options. Check whether a background-data-update push was sent while a visible alert was expected. Apple background notifications are not guaranteed, so they cannot serve as a certain substitute for visible notifications.[9]
With OneSignal, inspect whether foreground listeners or extension code suppress display. Do not remove an SDK or service without checking its relationship to other receive handlers.[13]
Web push needs its own checklist. Along with browser permission/subscription, check OneSignal Service Worker registration and operation and its arrangement with any existing PWA Service Worker. Support for receipt confirmation and support for web push itself are separate matters.[15]
Operations connected from observation to improvement — Respond using service indicators and alerts, then connect change records and incident reviews to improvements.
Do not change priority and TTL first to eliminate delay
Separate time spent in scheduling, sending limits and queues from time after provider acceptance. FCM can store messages while a device is offline and deliver after reconnection, but expired TTL prevents delivery. A new message can replace a pending one with the same registration token and collapse_key. Do not assume every message accumulates and arrives in sequence.[3]
Normal-priority Android FCM messages may be delayed in Doze. High priority attempts immediate delivery but is not a fix for every push. High-priority messages that do not produce user-visible notifications can be deprioritized or otherwise handled differently. Delivery priority and notification-channel importance are separate settings.[7][11]
TTL zero is not simply a delay fix: it discards messages that cannot be delivered immediately, making it unsuitable for messages that should arrive late rather than never. Do not copy Android/web TTL and APNs expiration as though they were one field; record the actual path's validity period.[3]
Reporting latency also differs. Firebase Received is available for Android FCM SDK 18.0.1 and later, while Impressions concerns displayed Android background notification messages. Do not extend these into equivalent iOS display checks. Collection has conditions such as Analytics configuration, and aggregate metrics can take up to 24 hours to appear. The separate aggregate FCM Data API is not an exhaustive ledger of every message either.[12]
Use message/device evidence for real-time reproduction and aggregate reports to compare patterns by OS, version and period. Do not resend to the same customer merely because an aggregate count has not yet increased.
Reproduction records need conditions and observations, not just “did not arrive”
Fix an owned or explicitly authorized test app/device and synthetic user first. Do not test against all-user segments or real customers. Keep raw tokens, credentials and personal data private, joining necessary identifiers only in restricted internal records.
At minimum record app/project, message/recipient identifiers, time/timezone, OS/app/SDK versions, app state, permission/channel, payload type, TTL/priority and observations at each stage. Preserve platform IDs and any FCM/APNs IDs separately without assuming they match. These fields are a design proposal connecting the preceding documentation.
Completed example: invisible in the foreground, visible in the background
This is a design example, not a real send or measurement. Versions, times and identifiers illustrate recordkeeping; they do not recommend adopting a particular SDK version.
| Shared field | Example value |
|---|---|
| Test scope | Owned development app and one test device; no real customers |
| Path | Test server → FCM HTTP v1 → Android; no OneSignal |
| Project / synthetic user / device alias | example-push-lab / example-user-01 / example-device-A |
| App / OS / SDK | App 1.0.0 (100) / Android 13 (API 33) / firebase-messaging:24.0.0 |
| Build conditions | compile SDK 34; target SDK 33; fixed example SDK version |
| Receiving-address record | Real token in restricted internal storage; only example-registration-A in shared records |
| Permission / channel | Notifications allowed; app-created diag enabled; HIGH importance |
| Network / device state | Same Wi-Fi; screen on; Do Not Disturb off; not force-stopped |
| Payload / delivery settings | Same notification + data content; normal priority; TTL 600 seconds; no separate collapse key |
| App code | Foreground callback logged; no code posting a foreground notification |
| Observation | Observe callback and system tray separately for 30 seconds after each send; this is an observation window, not a delivery guarantee |
Official release notes document SDK 24.0.0's compile SDK requirement. Real reproduction records must use the exact resolved/included build versions, not copied example numbers.[16]
| Observation | A: foreground | B: background |
|---|---|---|
| Request time | 2026-09-26 10:00:00 +09:00 | 2026-09-26 10:02:00 +09:00 |
| Shared message-ID alias | example-msg-A | example-msg-B |
| API observation | HTTP 200 and message ID | HTTP 200 and message ID |
| App receive callback | Observed at 10:00:01 | None during observation |
| System notification tray | No display | Display observed at 10:02:01 |
| Click / actual reading | Not clicked / not assessed | Not clicked / not assessed |
The intentionally varied condition is foreground versus background. Request times and message IDs differ to identify each send. FCM notification handling explains this hypothetical combination: A calls for investigation of foreground display after receipt; B can display a system notification without a receive callback.[8]
The next action is not to regenerate every credential. Decide whether the product should display in the foreground, then compare a separate build implementing that behavior if needed. If neither receipt nor display is evidenced, mark the stage unverified and return to targeting, acceptance, network and expiry conditions. Two tests do not establish delivery guarantees for all users.
The last verified stage determines the next action
If a permission or channel setting reproduces and resolves the cause, a new platform or observability product need not come first. Narrow hypotheses using directly observable device state and existing logs. Define integration review and operating support when configuration and responsibility span several apps, SDKs and push providers.
IXC app push adoption and onboarding describes support for SDK integration and channel configuration.
Do not end an incident record with “push did not arrive.” Record the target, the last verified stage and the next check so server, app and operations staff investigate the same problem.



