dispose method
Cancels FCM listeners, invalidates the FCM token, and resets state so initNotifications can run again on the next login.
Deleting the token ensures FCM stops delivering to this device for the logged-out user. A fresh token is generated on the next initNotifications call and registered for the new user.
Called by AuthenticationBloc when the user becomes unauthenticated.
Implementation
Future<void> dispose() async {
await _onMessageSub?.cancel();
await _onMessageOpenedAppSub?.cancel();
await _onTokenRefreshSub?.cancel();
_onMessageSub = null;
_onMessageOpenedAppSub = null;
_onTokenRefreshSub = null;
_initialized = false;
_lastKnownToken = null;
// Unblock any concurrent waiters before clearing so they are not left hanging.
if (_initCompleter != null && !_initCompleter!.isCompleted) {
_initCompleter!.complete();
}
_initCompleter = null;
// Fire-and-forget — deleteToken() is a network call and must not block
// the unauthenticated state emission, which would delay the login screen.
unawaited(
_firebaseMessaging
.deleteToken()
.then((_) {
_logger.info('[Notifications] FCM token deleted — FCM will stop delivering to this device for the logged-out user.');
// TODO: Tell backend to remove this token — NotificationService.deleteFCMToken()
})
.catchError((Object e, StackTrace st) {
// Non-fatal — token will eventually expire on the backend.
_logger.warn('[Notifications] Failed to delete FCM token.', error: e, stackTrace: st, escalate: false);
}),
);
_logger.info('[Notifications] Disposed.');
}