diff --git a/src/App.js b/src/App.js index c3e98bb..3c38374 100644 --- a/src/App.js +++ b/src/App.js @@ -13,6 +13,26 @@ import useInactivityLogout from 'hooks/useInactivityLogout'; // ==============================|| APP - THEME, ROUTER, LOCAL ||============================== // +// Was previously declared inline inside App(), which made it a fresh +// component reference on every App render — React would unmount/remount it +// each time, re-firing its useEffect (and the FCM permission toast) on +// every App re-render instead of once per app load. +const AppContent = () => { + useInactivityLogout(); + + useEffect(() => { + generateToken(); + initFirebaseNotificationListener(); + }, []); + + return ( + <> + + + + ); +}; + const App = () => { const navigate = useNavigate(); useEffect(() => { @@ -21,22 +41,6 @@ const App = () => { } }, [navigate]); - const AppContent = () => { - useInactivityLogout(); - - useEffect(() => { - generateToken(); - initFirebaseNotificationListener(); - }, []); - - return ( - <> - - - - ); - }; - return ( <> diff --git a/src/firebase_notification/notification.js b/src/firebase_notification/notification.js index eb88714..413683f 100644 --- a/src/firebase_notification/notification.js +++ b/src/firebase_notification/notification.js @@ -22,6 +22,12 @@ const opentoast = (message, color, vertical = 'bottom') => { }); }; +// Notification.requestPermission() re-resolves with the browser's current +// (often already-decided) permission every time this runs. Without a guard, +// any repeat call — e.g. from a remount — re-shows the same permanent, +// non-auto-dismissing toast and they stack up. Only warn once per tab. +let notificationWarningShown = false; + // ===================== Generate FCM Token ===================== export const generateToken = async () => { try { @@ -29,7 +35,10 @@ export const generateToken = async () => { dispatch(setFcmPermission(permission)); if (permission !== 'granted') { - opentoast('Enable notifications to receive OTP, alerts, and updates', 'error'); + if (!notificationWarningShown) { + notificationWarningShown = true; + opentoast('Enable notifications to receive OTP, alerts, and updates', 'error'); + } return; }