From 583d9f7428a369510b88a813cbd8dcc4fcd913cb Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Mon, 13 Apr 2026 16:51:26 +0530 Subject: [PATCH] feat: implement full FCM token cleanup on logout by deleting both remote and local tokens --- .../services/push_notification_service.dart | 24 +++++++++++++------ .../presentation/providers/auth_provider.dart | 9 ++++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/core/services/push_notification_service.dart b/lib/core/services/push_notification_service.dart index 1316a56..a6293a3 100644 --- a/lib/core/services/push_notification_service.dart +++ b/lib/core/services/push_notification_service.dart @@ -254,16 +254,26 @@ class PushNotificationService { _dispatchTap(Map.from(message.data)); } - /// Unregister FCM token from backend (call on logout). + /// Unregister FCM token from backend and delete locally (call on logout). Future unregister() async { - if (_currentToken == null) return; - try { - await _repo.removeFcmToken(_currentToken!); - debugPrint('[FCM] Token unregistered from backend'); - } catch (e) { - debugPrint('[FCM] Failed to unregister token: $e'); + // Remove from backend so it stops sending push to this device + if (_currentToken != null) { + try { + await _repo.removeFcmToken(_currentToken!); + debugPrint('[FCM] Token unregistered from backend'); + } catch (e) { + debugPrint('[FCM] Failed to unregister token: $e'); + } } _currentToken = null; + + // Delete the local FCM token so Firebase stops delivering notifications + try { + await _messaging?.deleteToken(); + debugPrint('[FCM] Local FCM token deleted'); + } catch (e) { + debugPrint('[FCM] Failed to delete local token: $e'); + } } /// Re-register token after login. diff --git a/lib/features/auth/presentation/providers/auth_provider.dart b/lib/features/auth/presentation/providers/auth_provider.dart index 3fc5973..fcdf364 100644 --- a/lib/features/auth/presentation/providers/auth_provider.dart +++ b/lib/features/auth/presentation/providers/auth_provider.dart @@ -78,6 +78,8 @@ class AuthNotifier extends StateNotifier { // when token refresh fails ApiClient.onForceLogout = () { SocketService().disconnect(); + // Delete local FCM token so push notifications stop + PushNotificationService().unregister(); // Only reset if still authenticated — avoid showing errors on login screen if (state.status == AuthStatus.authenticated) { state = const AuthState(); @@ -121,12 +123,13 @@ class AuthNotifier extends StateNotifier { state = const AuthState(); // Disconnect socket immediately SocketService().disconnect(); - // Clear tokens BEFORE any API calls to prevent 401 errors during logout - await SecureStorage.clearTokens(); - // Best-effort cleanup — tokens already cleared, ignore any errors + // Unregister FCM BEFORE clearing tokens — backend call needs auth header, + // and deleteToken() stops Firebase from delivering to this device try { await PushNotificationService().unregister(); } catch (_) {} + // Logout API call + clear local tokens + await _repository.logout(); } Future login({