From 01a916677f8d8368293dc8c8eaa613f5cefef807 Mon Sep 17 00:00:00 2001 From: biratdatta Date: Mon, 16 Sep 2024 01:08:22 +0530 Subject: [PATCH 1/3] feat: notification handling improvement task --- src/components/sidebar/index.tsx | 23 +++++++- src/config/firebase.ts | 36 +++++++++---- src/pages/_app.tsx | 90 +++++++++++++++++++++++--------- 3 files changed, 113 insertions(+), 36 deletions(-) diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 7a25c4d..1fc5725 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -53,6 +53,22 @@ export const Sidebar = ({ isOpen, onToggle }: { isOpen: boolean; onToggle: () => onToggle(); }; + const unregisterServiceWorkers = async () => { + if ('serviceWorker' in navigator) { + try { + const registrations = await navigator.serviceWorker.getRegistrations(); + if (registrations.length > 0) { + await Promise.all(registrations.map((registration) => registration.unregister())); + console.log('All service workers unregistered'); + } else { + console.log('No service workers registered'); + } + } catch (error) { + console.error('Failed to unregister service workers:', error); + } + } + }; + function logout() { removeCookie('access_token', { path: '/' }); const userType = sessionStorage.getItem('userType'); @@ -60,8 +76,11 @@ export const Sidebar = ({ isOpen, onToggle }: { isOpen: boolean; onToggle: () => sessionStorage.clear(); userType && sessionStorage.setItem('userType', userType); context?.setMessages([]); - router.push('/login'); - if (typeof window !== 'undefined') window.location.reload(); + + unregisterServiceWorkers().then(() => { + router.push('/login'); + if (typeof window !== 'undefined') window.location.reload(); + }); } console.log('debug', { config }); diff --git a/src/config/firebase.ts b/src/config/firebase.ts index 82a76ec..8306e29 100644 --- a/src/config/firebase.ts +++ b/src/config/firebase.ts @@ -11,17 +11,25 @@ const firebaseConfig = { measurementId: String(process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID), }; -let app; +let app: any; let messaging: any; export const initializeFirebase = () => { if (typeof window !== 'undefined' && !getApps().length) { app = initializeApp(firebaseConfig); - messaging = typeof window !== 'undefined' ? getMessaging(app) : null; + messaging = getMessaging(app); + console.log('Firebase initialized'); + } else { + console.log('Firebase already initialized or running on the server'); } }; export const requestForToken = async () => { + if (!messaging) { + console.error('Firebase is not initialized. Please initialize Firebase first.'); + return null; + } + if (typeof window !== 'undefined' && 'serviceWorker' in navigator) { try { const currentToken = await getToken(messaging, { @@ -31,21 +39,31 @@ export const requestForToken = async () => { return currentToken; } else { console.log('No registration token available. Request permission to generate one.'); + return null; } } catch (err) { - console.log('An error occurred while retrieving token:', err); + console.error('An error occurred while retrieving token:', err); + return null; } + } else { + console.error('Service Worker is not supported in this browser.'); + return null; } - return null; }; export const onMessageListener = () => { - if (typeof window !== 'undefined') { - return new Promise((resolve) => { + if (!messaging) { + console.error('Firebase is not initialized. Please initialize Firebase first.'); + return Promise.reject('Firebase not initialized'); + } + + return new Promise((resolve) => { + if (typeof window !== 'undefined') { onMessage(messaging, (payload) => { resolve(payload); }); - }); - } - return Promise.resolve(null); + } else { + resolve(null); + } + }); }; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c98a34b..5c02221 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -25,6 +25,30 @@ function SafeHydrate({ children }: { children: ReactElement }) { return
{typeof window === 'undefined' ? null : children}
; } +// Client-side check for the service-workers if they are expired or not + +// const unregisterServiceWorkerIfExpired = () => { +// const SW_EXPIRATION_KEY = 'serviceWorkerExpiration'; +// const EXPIRY_TIME = 30 * 24 * 60 * 60 * 1000; + +// const expiration = localStorage.getItem(SW_EXPIRATION_KEY); +// const currentTime = Date.now(); + +// if (expiration && currentTime > parseInt(expiration)) { +// if ('serviceWorker' in navigator) { +// navigator.serviceWorker.ready.then((registration) => { +// registration.unregister().then(() => { +// console.log('Service worker unregistered after 30 days'); +// localStorage.removeItem(SW_EXPIRATION_KEY); +// }); +// }); +// } +// } else { +// localStorage.setItem(SW_EXPIRATION_KEY, (currentTime + EXPIRY_TIME).toString()); +// console.log('Service worker expiration extended by 30 days'); +// } +// }; + const App = ({ Component, pageProps }: AppProps) => { const router = useRouter(); const { isAuthenticated, login } = useLogin(); @@ -47,34 +71,50 @@ const App = ({ Component, pageProps }: AppProps) => { }; useEffect(() => { - if (!sessionStorage.getItem('sessionId')) { - sessionStorage.setItem('sessionId', uuidv4()); - } - const firebaseConfig = encodeURIComponent( - JSON.stringify({ - apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, - authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, - measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, - }) - ); + if (isAuthenticated) { + initializeFirebase(); + + const getToken = async () => { + const permission = await Notification.requestPermission(); + if (permission === 'granted') { + const token = await requestForToken(); + if (token) { + console.log('your token is here', token); + setToken(token); + } + } else { + console.log('permission not granted'); + } + }; + + getToken(); - if ('serviceWorker' in navigator) { - navigator.serviceWorker - .register(`/firebase-messaging-sw.js?firebaseConfig=${firebaseConfig}`) - .then((registration) => { - console.log('Service Worker registered with scope:', registration.scope); + const firebaseConfig = encodeURIComponent( + JSON.stringify({ + apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, + authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, + measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, }) - .catch((err) => { - console.error('Service Worker registration failed:', err); - }); + ); + + if ('serviceWorker' in navigator) { + navigator.serviceWorker + .register(`/firebase-messaging-sw.js?firebaseConfig=${firebaseConfig}`) + .then((registration) => { + console.log('Service Worker registered with scope:', registration.scope); + }) + .catch((err) => { + console.error('Service Worker registration failed:', err); + }); + } + + // unregisterServiceWorkerIfExpired(); } - initializeFirebase(); - getToken(); - }, []); + }, [isAuthenticated]); const handleLoginRedirect = useCallback(() => { if (router.pathname === '/login' || router.pathname.startsWith('/otp')) { From a8584d94ad58099cbfac50e632cfaf2032d9d077 Mon Sep 17 00:00:00 2001 From: biratdatta Date: Tue, 17 Sep 2024 22:44:18 +0530 Subject: [PATCH 2/3] fix: minor changes --- src/components/sidebar/index.tsx | 25 ++-------- src/pages/_app.tsx | 82 ++++++++++++++++---------------- 2 files changed, 45 insertions(+), 62 deletions(-) diff --git a/src/components/sidebar/index.tsx b/src/components/sidebar/index.tsx index 1fc5725..472d729 100644 --- a/src/components/sidebar/index.tsx +++ b/src/components/sidebar/index.tsx @@ -53,22 +53,6 @@ export const Sidebar = ({ isOpen, onToggle }: { isOpen: boolean; onToggle: () => onToggle(); }; - const unregisterServiceWorkers = async () => { - if ('serviceWorker' in navigator) { - try { - const registrations = await navigator.serviceWorker.getRegistrations(); - if (registrations.length > 0) { - await Promise.all(registrations.map((registration) => registration.unregister())); - console.log('All service workers unregistered'); - } else { - console.log('No service workers registered'); - } - } catch (error) { - console.error('Failed to unregister service workers:', error); - } - } - }; - function logout() { removeCookie('access_token', { path: '/' }); const userType = sessionStorage.getItem('userType'); @@ -76,11 +60,8 @@ export const Sidebar = ({ isOpen, onToggle }: { isOpen: boolean; onToggle: () => sessionStorage.clear(); userType && sessionStorage.setItem('userType', userType); context?.setMessages([]); - - unregisterServiceWorkers().then(() => { - router.push('/login'); - if (typeof window !== 'undefined') window.location.reload(); - }); + router.push('/login'); + if (typeof window !== 'undefined') window.location.reload(); } console.log('debug', { config }); @@ -380,4 +361,4 @@ const getIconComponent = (iconName: string) => { } }; -export default Sidebar; +export default Sidebar; \ No newline at end of file diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5c02221..2df6879 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -25,36 +25,12 @@ function SafeHydrate({ children }: { children: ReactElement }) { return
{typeof window === 'undefined' ? null : children}
; } -// Client-side check for the service-workers if they are expired or not - -// const unregisterServiceWorkerIfExpired = () => { -// const SW_EXPIRATION_KEY = 'serviceWorkerExpiration'; -// const EXPIRY_TIME = 30 * 24 * 60 * 60 * 1000; - -// const expiration = localStorage.getItem(SW_EXPIRATION_KEY); -// const currentTime = Date.now(); - -// if (expiration && currentTime > parseInt(expiration)) { -// if ('serviceWorker' in navigator) { -// navigator.serviceWorker.ready.then((registration) => { -// registration.unregister().then(() => { -// console.log('Service worker unregistered after 30 days'); -// localStorage.removeItem(SW_EXPIRATION_KEY); -// }); -// }); -// } -// } else { -// localStorage.setItem(SW_EXPIRATION_KEY, (currentTime + EXPIRY_TIME).toString()); -// console.log('Service worker expiration extended by 30 days'); -// } -// }; - const App = ({ Component, pageProps }: AppProps) => { const router = useRouter(); const { isAuthenticated, login } = useLogin(); const [cookie, setCookie, removeCookie] = useCookies(); const [user, setUser] = useState(null); - + const [key, setKey] = useState(0); const [token, setToken] = useState(''); const getToken = async () => { @@ -72,21 +48,12 @@ const App = ({ Component, pageProps }: AppProps) => { useEffect(() => { if (isAuthenticated) { - initializeFirebase(); - const getToken = async () => { - const permission = await Notification.requestPermission(); - if (permission === 'granted') { - const token = await requestForToken(); - if (token) { - console.log('your token is here', token); - setToken(token); - } - } else { - console.log('permission not granted'); - } - }; + if (!sessionStorage.getItem('sessionId')) { + sessionStorage.setItem('sessionId', uuidv4()); + } + initializeFirebase(); getToken(); const firebaseConfig = encodeURIComponent( @@ -111,11 +78,46 @@ const App = ({ Component, pageProps }: AppProps) => { console.error('Service Worker registration failed:', err); }); } - - // unregisterServiceWorkerIfExpired(); } }, [isAuthenticated]); + if (typeof window !== 'undefined') { + window.updateFCMToken = (param: string) => { + console.log('updateFCMToken called'); + return 'updateFCMToken called' + param; + // TODO: save this token for this user + }; + + window.updateNotificationPayload = (stringifiedPayload: string) => { + console.log('updateNotificationPayload called with param', stringifiedPayload); + const payload = JSON.parse(stringifiedPayload); + const request = indexedDB.open('notificationDB', 1); + request.onerror = (event: any) => { + console.error('IndexedDB error:', event?.target?.error); + }; + request.onsuccess = (event: any) => { + const db = event?.target?.result; + const transaction = db.transaction(['notifications'], 'readwrite'); + const store = transaction.objectStore('notifications'); + + // Add the payload to IndexedDB + const addRequest = store.add({ ...payload, timestamp: Date.now() }); + + addRequest.onerror = (event: any) => { + console.error('Error adding payload to IndexedDB:', event.target.error); + }; + + addRequest.onsuccess = () => { + setKey((prevKey: any) => prevKey + 1); + console.log('Payload added to IndexedDB successfully'); + }; + }; + + return 'updateNotificationPayload processed'; + }; + } + + const handleLoginRedirect = useCallback(() => { if (router.pathname === '/login' || router.pathname.startsWith('/otp')) { // already logged in then send to home From 0fde6b864e38bc3829e047e625f7a3ac9b728e4d Mon Sep 17 00:00:00 2001 From: Birat Datta <88641794+biratdatta@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:50:30 +0530 Subject: [PATCH 3/3] Update _app.tsx --- src/pages/_app.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index cb7500f..d801f35 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -30,10 +30,7 @@ const App = ({ Component, pageProps }: AppProps) => { const { isAuthenticated, login } = useLogin(); const [cookie, setCookie, removeCookie] = useCookies(); const [user, setUser] = useState(null); - - const [key, setKey] = useState(0); - const [token, setToken] = useState(''); const getToken = async () => {