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, …)targetsinclude_aliases: { external_id: [userId] }.userIdis the alias. - Delivery truth: OneSignal returns
200with arecipientscount even for an empty audience, so the helpers treat delivery asrecipients >= 1(thedeliveredflag 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
PassPushOptions 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.
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
PKPushRegistryand, on an incoming VoIP push, reports a call to CallKit (CXProvider). iOS 13+ requires reporting a call for every VoIP push. The app’s.entitlementsneeds thevoipbackground 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.sendVoipPushToUserintentionally sendsdataonly. A customFirebaseMessagingServicestarts 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.