The lifecycle at a glance
Three calls drive everything above:init once at launch, identify when you
know who the user is, and reset when they leave. The SDK owns the rest: the
device key, the local cache, and the realtime connection (Centrifugo by default,
falling back to SSE).
The mental model
The SDK is a thin client that owns four things: a device identity, a local cache, a realtime connection, and (optionally) a set of prebuilt screens. Your app never holds SDK state. You make a few calls in, and reads come back to you as subscriptions, or the matching React hooks. See Architecture for the full picture.1. The first launch
ClarioDesk.init() runs once at app start. Import the secure RNG polyfill at the
very top of index.js, before anything else, then init:
init generates a non-extractable hardware keypair
(Secure Enclave or the Android Keystore on a dev build; a software P-256 key in
Expo Go) and registers the device with the backend. That keypair is the device’s
identity from then on, and it signs every request. On every later launch, init
finds the stored key and reuses it with no network round-trip. See
Authentication for how the keypair stands in for
tokens, and installation for the secure-storage
peer dependency.
2. Identify your user
Once your own auth knows who the user is, hand that down to ClarioDesk:identify is pure metadata. It does not grant access (the device key already
did that), so it is safe to call often, and it is idempotent: the same values
twice is a no-op.
When to call it
The right moment depends on the user’s state when ClarioDesk first runs. Each row below is a real case worth handling:| Scenario | What to do |
|---|---|
| New user signs in or signs up | Call identify right after your auth succeeds. |
| User was already signed in before you added (or updated to) the SDK | Call identify on launch from your persisted session. They never pass through login again, so a login-only hook misses them. |
| No user yet (anonymous) | Skip identify. Tickets still work; the device shows as unverified. |
| Anonymous user later signs in | Call identify at that point. The anonymous device and its existing tickets carry forward to the identified user. |
| Returning signed-in user (relaunch) | Call identify again on launch. It is idempotent, so this is a cheap no-op. |
| The user’s email or traits changed | Call identify again with the new values to update the device row. |
The existing-user trap
This is the case most integrations get wrong, so it is worth slowing down on. If you only callidentify from your login handler, you label the users who sign
in after you ship and nobody else. Everyone who was already logged in when you
released the update never visits your login screen again, so they stay unlabeled
devices, and your agents see “Unverified device” instead of an email.
The fix is to identify from your persisted session on every launch, not from the
login event:
Skipping
identify entirely is fine for anonymous feedback. Tickets still work;
they just arrive without an email. When the user signs in later, call identify
then and the existing device, and its ticket history, carry forward.3. Live by default
Afterinit (and identify, if you have a user), reads are live. You do not
poll. A hook primes from cache, then re-renders as the agent replies.
failed: true means render tap-to-retry). A send made
while offline waits in a durable outbox and flushes on reconnect. Watch the
realtime link with useConnection() to show an offline banner. See
Realtime for the connection states.
4. Logout and user switching
When the user signs out, callreset before clearing your own session:
reset revokes the device server-side (best effort), wipes the device key, and
clears local caches. The next init registers a brand-new device. For a user
switch on the same install (A to B without a restart), do the same and then
identify B:
5. Relaunches and reinstalls
| After this | Device identity | Ticket history |
|---|---|---|
| A normal relaunch | Same device; key reused with no network | Visible to the user |
reset() (logout or switch) | Wiped; next init() makes a fresh device | Detached from this device |
| An uninstall and reinstall | The stored key may be gone, so init() can register a fresh device | Starts clean on the new device |
identify
on a fresh device to reattach their email and traits.
Your integration checklist
For an app already in production:-
react-native-get-random-valuesis imported first, at the top ofindex.js. -
initruns at app start, before any support screen. -
identifyruns on launch from your persisted session, not only on login. -
resetruns on logout and on user switch. - Tickets render from
useTickets()/useMessages()(or the prebuilt UI). - Optional:
useConnection()drives an offline indicator.
Where to go next
Lifecycle event reference
The same four events as a tight code reference.
API reference
Every method, subscription, hook, and type.
Authentication
Why the device key replaces tokens.
Installation & Expo
Peer deps, the config plugin, dev build vs Expo Go.