Skip to Content
MobilePush notifications

Push notifications

Push is built on Firebase Cloud Messaging via @react-native-firebase, wrapped by src/services/PushNotificationService.js.

Initialization flow

initialize() runs after login and:

  1. Requests permission (requestPermission()).
  2. Gets the FCM token (getToken()).
  3. Registers handlers (foreground onMessage, background handler, notil-tap navigation).
  4. Sends the token to the API so the backend can target the device (/account/push-notification/fcm-token).

Permissions

  • iOS — Firebase messaging permission prompt (requestPermission(messaging)).
  • Android 13+ — the runtime POST_NOTIFICATIONS permission via PermissionsAndroid.request.

[!IMPORTANT] The Android permission dialog needs a foreground Activity. Requesting it during cold start / while backgrounded throws “Tried to use permissions API while not attached to an Activity.” The service guards the request on AppState.currentState === 'active' and retries on the next foreground (recheckPermissionAndInitialize, called on app resume).

Getting the FCM token

  • iOS must registerDeviceForRemoteMessages() and wait for an APNs token (with retry/backoff) before getToken() — otherwise it fails.
  • Transient getToken failures (e.g. “network connection was lost” while backgrounded) are expected and are not reported to Sentry as errors.

Message handling

  • ForegroundonMessage surfaces an in-app toast.
  • Background / quit — a background message handler is registered at module load (outside any component, as FCM requires); tapping a notification routes to the relevant screen via navigationRef.
  • Topics — subscribe/unsubscribe helpers exist for broadcast segments.

The app also uses Firebase Remote Config (feature flags / config) and Analytics. Remote Config fetches can fail transiently when offline; like FCM token errors, those are treated as expected and filtered from Sentry.

Last updated on