This commit is contained in:
pradeepkumar
2026-04-06 14:06:55 +05:30
parent cfc6cd540a
commit 62545d0114
2 changed files with 62 additions and 14 deletions

View File

@@ -47,7 +47,7 @@ export function NotificationProvider() {
const registered = await notificationService.requestPermissionAndRegister(); const registered = await notificationService.requestPermissionAndRegister();
console.log('[NotificationProvider] Registration result:', registered); console.log('[NotificationProvider] Registration result:', registered);
if (registered) { if (registered) {
unsubscribe = notificationService.setupForegroundHandler((payload) => { unsubscribe = await notificationService.setupForegroundHandler((payload) => {
console.log('[NotificationProvider] Foreground message received:', payload); console.log('[NotificationProvider] Foreground message received:', payload);
addToast(payload); addToast(payload);
}); });

View File

@@ -1,27 +1,65 @@
import { app, getMessaging, getToken, onMessage, isSupported } from '@/lib/firebase';
import api from './api'; import api from './api';
const VAPID_KEY = process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY; const VAPID_KEY = process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY;
class NotificationService { class NotificationService {
private currentToken: string | null = null; private currentToken: string | null = null;
private messaging: any = null;
private async getFirebaseMessaging() {
if (this.messaging) return this.messaging;
try {
const { getMessaging, isSupported } = await import('firebase/messaging');
const supported = await isSupported();
if (!supported) {
console.log('[Notifications] Firebase messaging not supported');
return null;
}
const { initializeApp, getApps } = await import('firebase/app');
const firebaseConfig = {
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,
};
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
this.messaging = getMessaging(app);
return this.messaging;
} catch (error) {
console.error('[Notifications] Failed to init Firebase messaging:', error);
return null;
}
}
async requestPermissionAndRegister(): Promise<boolean> { async requestPermissionAndRegister(): Promise<boolean> {
try { try {
// Check if messaging is supported in this browser if (typeof window === 'undefined') return false;
const supported = await isSupported();
if (!supported) {
console.log('[Notifications] Firebase messaging not supported in this browser');
return false;
}
if (!VAPID_KEY) { if (!VAPID_KEY) {
console.warn('[Notifications] VAPID key not configured'); console.warn('[Notifications] VAPID key not configured');
return false; return false;
} }
if (!('Notification' in window)) {
console.log('[Notifications] Notifications API not available');
return false;
}
if (!('serviceWorker' in navigator)) {
console.log('[Notifications] Service workers not supported');
return false;
}
const messaging = await this.getFirebaseMessaging();
if (!messaging) return false;
// Request notification permission // Request notification permission
const permission = await Notification.requestPermission(); const permission = await Notification.requestPermission();
console.log('[Notifications] Permission:', permission);
if (permission !== 'granted') { if (permission !== 'granted') {
console.log('[Notifications] Permission denied'); console.log('[Notifications] Permission denied');
return false; return false;
@@ -31,9 +69,13 @@ class NotificationService {
const registration = await navigator.serviceWorker.register( const registration = await navigator.serviceWorker.register(
'/firebase-messaging-sw.js' '/firebase-messaging-sw.js'
); );
console.log('[Notifications] Service worker registered:', registration.scope);
// Wait for service worker to be ready
await navigator.serviceWorker.ready;
// Get FCM token // Get FCM token
const messaging = getMessaging(app); const { getToken } = await import('firebase/messaging');
const token = await getToken(messaging, { const token = await getToken(messaging, {
vapidKey: VAPID_KEY, vapidKey: VAPID_KEY,
serviceWorkerRegistration: registration, serviceWorkerRegistration: registration,
@@ -44,6 +86,7 @@ class NotificationService {
return false; return false;
} }
console.log('[Notifications] FCM token obtained:', token.substring(0, 20) + '...');
this.currentToken = token; this.currentToken = token;
// Register token with backend // Register token with backend
@@ -52,7 +95,7 @@ class NotificationService {
device: 'web', device: 'web',
}); });
console.log('[Notifications] FCM token registered'); console.log('[Notifications] FCM token registered with backend');
return true; return true;
} catch (error) { } catch (error) {
console.error('[Notifications] Registration failed:', error); console.error('[Notifications] Registration failed:', error);
@@ -73,12 +116,16 @@ class NotificationService {
} }
} }
setupForegroundHandler( async setupForegroundHandler(
callback: (payload: { title: string; body: string; data?: Record<string, string> }) => void callback: (payload: { title: string; body: string; data?: Record<string, string> }) => void
): (() => void) | null { ): Promise<(() => void) | null> {
try { try {
const messaging = getMessaging(app); const messaging = await this.getFirebaseMessaging();
if (!messaging) return null;
const { onMessage } = await import('firebase/messaging');
const unsubscribe = onMessage(messaging, (payload) => { const unsubscribe = onMessage(messaging, (payload) => {
console.log('[Notifications] Foreground message:', payload);
callback({ callback({
title: payload.notification?.title || 'New Notification', title: payload.notification?.title || 'New Notification',
body: payload.notification?.body || '', body: payload.notification?.body || '',
@@ -86,7 +133,8 @@ class NotificationService {
}); });
}); });
return unsubscribe; return unsubscribe;
} catch { } catch (error) {
console.error('[Notifications] Foreground handler failed:', error);
return null; return null;
} }
} }