arch-atlas

FCM Token Sync (per-role)

core/network/dio_helper.dart · syncFcmTokenForAllRoles + _checkAndSendFcmToken

data

Overview

Backend cares which (auth_token, fcm_token) pairs are active — the customer and seller tokens get separate FCM registrations. DioHelper owns this side channel, keyed by the tuple in SharedPreferences so a re-send only fires on actual change.

User Flow

  1. First-of-session: on the first authenticated request, _checkAndSendFcmToken fires fire-and-forget for that auth token.
  2. syncFcmTokenForAllRoles is explicitly called after login to register both tokens if dual login succeeded.
  3. _checkAndSendFcmToken uses a separate raw Dio (not the singleton) to avoid interceptor recursion.
  4. AuthStorageService.isFcmTokenSent / markFcmTokenSent dedupe by (fcmToken, last20charsOfAuthToken).

Cases & Edge Cases

  • _fcmSyncInProgress Set prevents two parallel requests with the same auth token from each sending the FCM token (burst-at-startup race).
  • Empty fcmToken is a hard 'skip' — happens before FirebaseMessaging permission resolves.
  • Token-tracking keys are never cleared on logout — fine, because clearSession wipes the tokens themselves and the keys become orphaned but harmless.

Code References

  • lib/src/core/network/dio_helper.dart:64 // syncFcmTokenForAllRoles
  • lib/src/core/network/dio_helper.dart:82 // _checkAndSendFcmToken
  • lib/src/core/services/auth_storage.dart:219 // _getFcmTrackingKey

API Calls

  • POST/fcm/tokenno status

    Register the device's FCM token for a given auth scope so the backend can target push to this device + role.

    Request
    { token: string /* fcmToken */ } + header `Authorization: Bearer <authToken>` + `x-publishable-api-key`
    Response
    200 / 201 (no body)
    lib/src/core/network/dio_helper.dart:82 // _checkAndSendFcmToken

    auth: bearer (per role). Fired via raw Dio (avoids interceptor recursion). Triggered on first authenticated request post-login and on onTokenRefresh. Deduped via 'fcm_sent_<fcmToken>_<authSuffix>' SharedPreferences keys.

Notes

When debugging missing pushes, first verify the right key in SharedPreferences exists ('fcm_sent_<token>_<suffix>') — if missing, the upload never fired.