Skip to content

feat(ios): emit tokenReceived event when FCM token is issued#190

Open
eljass wants to merge 1 commit into
capacitor-community:masterfrom
eljass:upstream/feat-token-received-ios
Open

feat(ios): emit tokenReceived event when FCM token is issued#190
eljass wants to merge 1 commit into
capacitor-community:masterfrom
eljass:upstream/feat-token-received-ios

Conversation

@eljass

@eljass eljass commented May 7, 2026

Copy link
Copy Markdown

What

Adds a tokenReceived event JS clients can subscribe to for live FCM registration token updates on iOS. Partially addresses #177 (Android follow-up planned).

Implementation:

  • Plugin.swift messaging(_:didReceiveRegistrationToken:) now calls notifyListeners("tokenReceived", ["token": token])
  • Gated on Messaging.messaging().apnsToken != nil so the pre-APNs registration token Firebase mints on first launch (which gets immediately replaced) is not emitted to consumers — this prevents persisting a stale token in the consumer's backend
  • Deduped against lastNotifiedToken so foreground/background transitions do not re-emit the same token

JS API:

FCM.addListener('tokenReceived', ({ token }) => {
  await saveFcmToken(token);
});

Why

Issue #177 asks for a way to monitor token refresh without polling getToken(). iOS already had a MessagingDelegate callback wired up — it just discarded the token after caching. This change forwards the value to JS.

Test plan

  • Listener fires once after PushNotifications.register() resolves (post-APNs)
  • Does not fire for the pre-APNs token Firebase issues on first launch
  • Does not fire twice for the same token across foreground/background transitions
  • Verified in our app on iOS 14+ with Firebase iOS SDK 11.x

Notes

  • getToken() behaviour is unchanged. Purely additive.
  • No new dependencies.
  • Belt-and-suspenders recommendation for consumers: still call getToken() once after PushNotifications.register() resolves, in case Firebase has already minted (and cached) a token before the listener attaches. Tokens minted before the listener registers are not buffered in this PR — adding a buffer would be a larger behavioural change and is left for a separate discussion.
  • Android follow-up will arrive as a separate PR (uses @capacitor/push-notifications as a peer dependency, since FCM and PushNotifications cannot both register a FirebaseMessagingService independently). Issue How to Monitor token refresh on android/ios using this plugin #177 will close once both land.

Related PR

This stacks on top of #189 (fix(ios): refreshToken race), but the diffs do not overlap — both can be reviewed and merged independently.

Adds a `tokenReceived` event JS clients can subscribe to for live FCM
registration token updates on iOS. Addresses the long-standing request
in capacitor-community#177.

Implementation:
- Plugin.swift `messaging(_:didReceiveRegistrationToken:)` now calls
  `notifyListeners("tokenReceived", ["token": token])`
- Gated on `Messaging.messaging().apnsToken != nil` so the pre-APNs
  registration token Firebase mints on first launch (which gets
  immediately replaced) is not emitted to consumers
- Deduped against `lastNotifiedToken` so foreground/background
  transitions do not re-emit the same token

JS API:

    FCM.addListener('tokenReceived', ({ token }) => { ... });

`getToken()` behaviour is unchanged; this PR is purely additive. No new
dependencies. The Android side will arrive in a follow-up PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant