When an agent replies (or a ticket’s status changes) while the user is away,
ClarioDesk can fire an OS push notification. The host app owns the platform
notification handler; ClarioDesk validates its payload, refreshes authorized
support state, and provides the routing surface supported by the installed SDK
version.
How it’s wired
Push goes through a PushTokenProvider seam rather than importing a messaging
library directly. Your app owns the Firebase/FCM plugin; the SDK just asks it
for a token. This keeps Firebase’s native code out of hosts that don’t want
push.
- React Native: push lives in a separate package,
@clariodesk/react-native-push, so Firebase never autolinks into a headless
host’s binary. See the RN push guide.
- Flutter: the
PushTokenProvider abstraction lets you hand the SDK an FCM
token without the SDK depending on firebase_messaging.
- Swift (native iOS): no Firebase at all — forward the raw APNs token with
ClarioDesk.setAPNSDeviceToken(token) from your AppDelegate. See the
Swift push guide.
Delivery and attention
End-user push goes out via FCM HTTP v1. iOS is reached through FCM → APNs.
Each customer uploads their own service-account JSON per app in the dashboard,
so notifications come from your own Firebase project.
Native Swift hosts skip Firebase entirely: upload an APNs auth key (.p8)
instead, and delivery goes straight to APNs from your own Apple credentials.
The attention-aware backend uses this contract: only the visibly
focused support inbox or matching ticket may suppress a banner, and only after
it confirms that the specific realtime event rendered. Outside support,
backgrounded, or killed, the notification alerts immediately. A stale visible
surface that does not acknowledge the event falls back to an alert within a
short bounded window, so one support question cannot disappear indefinitely.
Every SDK 0.3.0+ exposes support-surface visibility and authenticated target
resolution. Older 0.2.x packages never suppress from presence and receive
immediate generic alerts. Check the installed version before wiring these APIs.
Payload privacy
Notification data is a content-free invalidation envelope. It contains the
destination device, identity epoch, event nonce, and (on the new envelope) an
opaque delivery id—but no ticket id, message id, customer id, message body, or
preview. The SDK resolves the opaque id through a signed request after checking the
current device, identity epoch, app, customer, and target access. Never put or
read a raw ticketId in FCM/APNs data.
Handling a tap
Route ClarioDesk messages in your shared push handler so they don’t collide
with your app’s own notifications. SDK 0.3.0+ resolves the authenticated
target after a tap:
Prebuilt UI calls ClarioDeskWidgets.openFromPush(...) on Flutter/Swift or
openFromPush(data) from the React Native UI package. Older 0.2.x
openTicketFromPush validates/refreshes and falls back to the inbox.
Custom-screen visibility
Only assert a surface while its route is actually focused:
React Native uses useVisibleSupportSurface({ kind: 'ticket', ticketId }, useIsFocused()) (or the imperative set/clear methods). Swift uses
setVisibleSupportSurface(.ticket(ticketId)) on focus and clears on blur.
Every SDK clears the lease on app background, logout, identity switch, and
reset, then restores it on resume only if the same route remains focused. Each
prebuilt navigator manages this automatically.
Background, killed, and foreground taps
Wire all three states:
- Background: handle the platform notification-open callback.
- Killed: read the platform’s initial notification once, then wait until
ClarioDesk.init and the host router are ready before navigating.
- Foreground outside support: mobile OSes may not display a remote banner;
use the host app’s existing in-app banner/local-notification layer.
If the notification belongs to ClarioDesk, return early from the shared
handler so the host’s unrelated push logic does not process it a second time.
For a custom UI, notification navigation always belongs to the host router.
For prebuilt UI, navigation belongs to the prebuilt modal—do not mix them.
React Native: registering the background message handler in index.js at
startup is the #1 push setup-failure cause. Make sure it runs at app entry, not
inside a component.
See the RN push guide for the full Firebase wiring.