DEV Community

ZèD
ZèD

Posted on • Edited on

Send FCM Event to All Opened Client Windows Instead of Focused (FCM Default)

Enhancing Multi-Tab Synchronization with Custom FCM Handling in Service Workers

Firebase Cloud Messaging (FCM) delivers push notifications by default to a browser’s focused tab. This article presents a service worker implementation that broadcasts FCM events to all active client windows, enabling real-time synchronization in multi-tab applications.

Core Implementation Strategy

The service worker employs the following key functionalities:

  1. Immediate Service Worker Activation

    • Uses skipWaiting() during installation and clients.claim() during activation to control pages instantly.
  2. Broadcasted Push Event Handling

    • Intercepts FCM push events, extracts payload data, and distributes messages to all open tabs via clients.matchAll(), ensuring universal event propagation.
  3. Notification Click Management

    • Captures notification clicks, encodes payload data into URL parameters, and directs users to a relevant page.
  4. Firebase Initialization

    • Configures Firebase with placeholder values to prevent initialization errors while maintaining custom push handling.

Optimized Service Worker Code

self.addEventListener('install', () => self.skipWaiting()); self.addEventListener('activate', (event) => event.waitUntil(self.clients.claim())); self.importScripts('/firebase/firebase-app-compat.js', '/firebase/firebase-messaging-compat.js'); self.addEventListener('notificationclick', (event) => { event.notification.close(); const data = event.notification.data.FCM_MSG?.data; if (data) { const url = `/?pnBgClick=${btoa(JSON.stringify(data))}`; event.waitUntil(self.clients.openWindow(url)); } }); self.addEventListener('push', async (event) => { const payload = event.data.json().data; if (!payload) return; const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); clients.forEach(client => client.postMessage({ type: 'push-notification', payload })); }); firebase.initializeApp({ apiKey: true, projectId: true, messagingSenderId: true, appId: true }); firebase.messaging(); 
Enter fullscreen mode Exit fullscreen mode

Client-Side Integration Example (React):

useEffect(() => { const handler = (event) => { /* Handle message */ }; navigator.serviceWorker.addEventListener('message', handler); return () => navigator.serviceWorker.removeEventListener('message', handler); }, []); 
Enter fullscreen mode Exit fullscreen mode

Key Advantages

  • Cross-Tab Consistency: Ensures simultaneous updates across all active tabs for unified user experiences.
  • Customization Flexibility: Extends beyond FCM defaults, enabling tailored event handling.
  • Enhanced Engagement: Delivers real-time updates to all sessions, improving responsiveness.

Conclusion

This implementation addresses FCM’s default single-tab targeting by leveraging service workers to broadcast events universally. Ideal for collaborative tools, chat applications, or any multi-tab interface requiring real-time synchronization, this approach guarantees consistent user experiences across all active sessions.

Top comments (0)