> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clariodesk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Push notifications

> Deep-link straight to the right ticket when the user taps a notification.

When an agent replies (or a ticket's status changes) while the user is away,
ClarioDesk can fire an OS push notification. On tap, the SDK opens itself
directly to the relevant ticket, with no host-side routing logic required.

## 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](/react-native/push).
* **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](/swift/push).

## Delivery

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 backend is presence-aware: if the user is actively connected, the push
is suppressed (they're already seeing the reply live).

## Handling a tap

Route ClarioDesk messages in your shared push handler so they don't collide with
your app's own notifications, then deep-link on tap:

<CodeGroup>
  ```dart Flutter theme={null}
  // In your push handler:
  ClarioDesk.handlePushPayload(payload);
  ```

  ```ts React Native theme={null}
  // Distinguish ours in a shared background handler:
  if (ClarioDesk.isClarioMessage(msg.data ?? {})) return;

  // On notification tap:
  ClarioDesk.openTicketFromPush(data); // or the usePushOpened() hook
  ```
</CodeGroup>

<Warning>
  **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.
</Warning>

See the [RN push guide](/react-native/push) for the full Firebase wiring.
