Skip to main content
How push works across the kit, how to send high-priority pushes, and the exact path to add full VoIP calling on top.

How standard push works

One identity, both directions:
  • App → OneSignal: on login the app calls OneSignal.login(user.id), setting the OneSignal External ID to the account’s immutable UUID. It fans out to all of the user’s devices.
  • Server → OneSignal: sendPushToUser(userId, …) targets include_aliases: { external_id: [userId] }. userId is the alias.
  • Delivery truth: OneSignal returns 200 with a recipients count even for an empty audience, so the helpers treat delivery as recipients >= 1 (the delivered flag the admin panel and the “test notification” button surface).
Everything is a no-op that returns false when ONESIGNAL_APP_ID / ONESIGNAL_API_KEY are unset — the kit ships push off by default.
push.service.ts is the whole server surface: sendPushToUser, sendPushBroadcast, and sendVoipPushToUser (a ready-made helper — see below).

High-priority / time-sensitive pushes

Pass PushOptions to raise priority and shorten the delivery window:
This is enough for high-priority alerts on both platforms without any native work. It is not enough for a native call UI — that is VoIP.

VoIP-ready server layer (included)

sendVoipPushToUser(userId, data, options?) sends a voip APNs push through a separate OneSignal app (ONESIGNAL_VOIP_APP_ID / ONESIGNAL_VOIP_API_KEY), with call-appropriate defaults (apns_push_type_override: 'voip', content_available: true, ttl: 30). It targets the same External ID alias, so identity needs no extra work.
Why a separate OneSignal app: iOS VoIP requires a VoIP-type APNs certificate, and a OneSignal app holds one APNs certificate. So calls need their own OneSignal app with the VoIP cert; standard notifications keep using ONESIGNAL_APP_ID. This is only the server half — on its own the push arrives, but nothing rings the device.

Adding full native VoIP

What’s left is native and platform-specific — the exact shape of a working implementation:
  • iOS — PushKit + CallKit. A Capacitor plugin registers PKPushRegistry and, on an incoming VoIP push, reports a call to CallKit (CXProvider). iOS 13+ requires reporting a call for every VoIP push. The app’s .entitlements needs the voip background mode.
  • Android — high-priority FCM + ConnectionService. The call push must be data-only (no notification/headings/contents), or FCM routes it to the tray and your service never runs. sendVoipPushToUser intentionally sends data only. A custom FirebaseMessagingService starts a foreground service and posts a full-screen-intent notification.
  • Web. No true VoIP — a “call” is a high-priority notification via the OneSignal service worker.

Checklist to go live with calls

1

OneSignal VoIP app

Create a second OneSignal app for VoIP; upload the Apple VoIP APNs certificate to it. Set ONESIGNAL_VOIP_APP_ID / ONESIGNAL_VOIP_API_KEY.
2

Native pieces

Add the iOS PushKit/CallKit plugin + voip entitlement; register the VoIP token on login. Add the Android data-only FirebaseMessagingService + ConnectionService + full-screen intent.
3

Signal & test

Call sendVoipPushToUser(...) from your call-signaling code. Test on physical devices — CallKit and VoIP pushes do not work in the iOS Simulator.