Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
student_panel
/
src
/
lib
/
firebase
:
useSyncFCMToken.ts
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
/** * React Hook for Monitoring FCM Token Changes * * This hook monitors the FCM token and detects when it changes. * FCM tokens can change when: * - Service worker is re-registered * - User clears browser data * - Token expires or is refreshed by Firebase * - Browser/app is updated * * Since there's no separate update-token API endpoint, this hook: * - Monitors token changes * - Stores the latest token locally * - Logs warnings when token changes while logged in * - The new token will be sent on next login */ import { useEffect, useRef } from 'react'; import { useSelector } from 'react-redux'; import { initializeFirebase, getFCMToken } from './init'; import { RootState } from '@/components/store'; // Storage key for last known FCM token const FCM_TOKEN_STORAGE_KEY = 'eschool_fcm_token'; /** * Hook to monitor FCM token changes * * Features: * - Automatically checks for token changes * - Stores latest token in localStorage * - Logs warnings when token changes while logged in * - Only runs when user is authenticated * - Prevents duplicate checks * * Note: Since there's no separate update-token API endpoint, * the new token will be sent to backend on next login. * * Usage: Call this hook once in your main dashboard layout */ export function useSyncFCMToken() { // Track if check is in progress to prevent duplicate calls const isCheckingRef = useRef(false); // Track if initial check is complete const hasInitialCheckRef = useRef(false); // Track if we've already shown warning for this session const hasShownWarningRef = useRef(false); // Get authentication state from Redux const { isAuthenticated, token: authToken } = useSelector( (state: RootState) => state.studentAuth ); useEffect(() => { // Only monitor if user is authenticated if (!isAuthenticated || !authToken) { // console.log( // '[FCM Monitor] User not authenticated, skipping FCM monitoring' // ); return; } // Don't check if already in progress if (isCheckingRef.current) { // console.log('[FCM Monitor] Check already in progress, skipping'); return; } // Function to check FCM token async function checkFCMToken() { try { isCheckingRef.current = true; // console.log('[FCM Monitor] Checking FCM token...'); // Initialize Firebase if not already done await initializeFirebase(); // Check if notifications are supported and permission is granted if (!('Notification' in window)) { // console.log( // '[FCM Monitor] Notifications not supported in this browser' // ); return; } if (Notification.permission !== 'granted') { // console.log('[FCM Monitor] Notification permission not granted'); return; } // Get current FCM token from Firebase const currentToken = await getFCMToken(); if (!currentToken) { // console.log('[FCM Monitor] No FCM token available'); return; } // console.log( // '[FCM Monitor] Current token:', // currentToken.substring(0, 20) + '...' // ); // Get stored token from localStorage (token sent during login) const storedToken = localStorage.getItem(FCM_TOKEN_STORAGE_KEY); // console.log( // '[FCM Monitor] Token sent at login:', // storedToken ? storedToken.substring(0, 20) + '...' : 'None' // ); // Check if token has changed const hasTokenChanged = storedToken && currentToken !== storedToken; if (!storedToken) { // First time - store the current token // console.log('[FCM Monitor] Storing initial FCM token'); localStorage.setItem(FCM_TOKEN_STORAGE_KEY, currentToken); hasInitialCheckRef.current = true; } else if (hasTokenChanged) { // Token changed while user is logged in! // console.warn( // '⚠️ ═══════════════════════════════════════════════════════' // ); // console.warn('[FCM Monitor] ⚠️ FCM TOKEN HAS CHANGED!'); // console.warn( // '[FCM Monitor] Old token:', // storedToken.substring(0, 30) + '...' // ); // console.warn( // '[FCM Monitor] New token:', // currentToken.substring(0, 30) + '...' // ); // console.warn('[FCM Monitor]'); // console.warn('[FCM Monitor] ⚠️ IMPORTANT: Backend has OLD token!'); // console.warn( // '[FCM Monitor] Notifications may NOT work until next login.' // ); // console.warn('[FCM Monitor]'); // console.warn( // '[FCM Monitor] 💡 SOLUTION: User needs to logout and login again' // ); // console.warn( // '[FCM Monitor] The new token will be sent during login.' // ); // console.warn( // '⚠️ ═══════════════════════════════════════════════════════' // ); // Store the new token for future comparison localStorage.setItem(FCM_TOKEN_STORAGE_KEY, currentToken); // Show user-friendly warning once per session if (!hasShownWarningRef.current) { hasShownWarningRef.current = true; // You could show a toast notification here // console.warn( // '[FCM Monitor] 💡 TIP: If notifications stop working, please logout and login again.' // ); } } else { // Token unchanged // console.log('[FCM Monitor] ✅ Token unchanged, all good!'); hasInitialCheckRef.current = true; } } catch (error) { console.error('[FCM Monitor] ❌ Error checking token:', error); } finally { isCheckingRef.current = false; } } // Run initial check after a short delay // This gives time for authentication to fully settle const timeoutId = setTimeout(() => { checkFCMToken(); }, 2000); // 2 second delay // Set up periodic check every 3 minutes // This catches any token refreshes that happen during the session const intervalId = setInterval(() => { if (!isCheckingRef.current) { // console.log('[FCM Monitor] Periodic token check...'); checkFCMToken(); } }, 3 * 60 * 1000); // 3 minutes // Cleanup function return () => { clearTimeout(timeoutId); clearInterval(intervalId); }; }, [isAuthenticated, authToken]); // Re-run when auth state changes // This hook doesn't return anything // It just runs in the background to monitor token changes } /** * Clear stored FCM token * * Call this function when user logs out to clear the stored token. * This ensures a fresh token check on next login. */ export function clearStoredFCMToken() { localStorage.removeItem(FCM_TOKEN_STORAGE_KEY); // console.log('[FCM Sync] Stored token cleared'); }