Cariosan

Push notifications

Notify users of new messages when the app is closed — FCM, minimal payload, bring-your-own Firebase.

3 min readUpdated May 31, 2026

Push delivers a notification when a new message arrives in a channel the user belongs to — even with the app closed. It's FCM-only (one API covering Android, iOS via APNs, and Web), opt-in, and privacy-first: only a title is ever sent, never the message body.

How it works

  1. The client obtains an FCM registration token from the device and calls client.registerDevice(token, platform).
  2. On a new message, the server looks up every other channel member's device tokens and sends a minimal FCM notification — "{sender} sent a message" plus channel_id + message_id in the data payload.
  3. The app fetches the actual content after it opens (using the ids) — so message text never transits the push network. This matters for healthtech/fintech.

The send is fire-and-forget and never blocks the message send path; the sender is excluded from their own pushes.

register.ts
// After getting a token from Expo / the FCM SDK:
await client.registerDevice(fcmToken, "android"); // "ios" | "android" | "web"
 
// On logout:
await client.unregisterDevice(fcmToken);

A token belongs to the device, not to an account.

  • Registering moves it. Registering a token again while another user is signed in moves it to that user, so a shared device only receives pushes for whoever is signed in now.
  • Unregistering only touches your own. unregisterDevice (DELETE /v1/me/devices?token=…) removes the token only if it is registered to the caller. For any other token it does nothing and still answers 204, so it cannot be used to switch off someone else's notifications or to learn whether a token is registered.
  • Unregister before you sign out. Call it on logout before you discard the user's chat token, because the request needs that token.

Enabling it (self-host = BYO Firebase)

Push is off by default — device registration is accepted, but nothing is delivered until you configure Firebase:

  1. Create a Firebase project and download a service-account JSON key.
  2. Set CARIOS_FCM_SERVICE_ACCOUNT_FILE (and optionally CARIOS_FCM_PROJECT_ID) — see environment.
  3. For iOS, upload an APNs auth key to the Firebase project (Apple Developer account). No server-side APNs code is needed — FCM routes to APNs.

FCM is free (no per-push charge). The self-hoster supplies their own Firebase — Cariosan charges nothing.

Minimal payload by default

Notifications carry a title only. The body is intentionally omitted; the app fetches content after opening via the channel_id/message_id in the data payload. There's no server config to include the body — privacy is the default, not an option.

Was this page helpful?

On this page