javascriptreactjsfirebase-cloud-messagingservice-workerweb-push

How to integrate firebase version 9 in ReactJS for web push notifications with a single service worker file


I am trying to add firebase web push notification for a React App built with Create React app version 5. The integration is working fine. I noticed that with the newer version, we have access to the service-worker.js file out of the box. Since the file will be part of the build process, we can supply our environmental variables directly in that file. Which wasn't the case in Create React app version 3 or older.

We need to make some modifications to the service worker code. In the current integration, we have to add an empty firebase-messaging-sw.js as mentioned in the documentation. I have added the firebase initialization script in the service-worker.js file itself as shown below.

const firebaseApp = initializeApp({
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGE_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
});

For some reason, the getToken never gets triggered. It only works if I downgrade from firebase v9 to v8 and use the old syntax. My requirement is I want to use firebase v9 and use a single service worker file with the firebase code in it along with the other service worker code.


Solution

  • I was able to solve this by adding the firebase v9 code in the default service-worker.js file. I needed to pass the active service worker which has the firebase code to the getToken function as shown below

    /**
     * Need to pass the service worker that has the firebase code
     */
    const sw = await navigator.serviceWorker.getRegistration();  // <-- get the active service worker
    getToken(messaging, {
      serviceWorkerRegistration: sw // <-- pass that to the getToken function
    })
    

    If you have more than one service worker in your application then navigator.serviceWorker.getRegistration() will return an array. We need to pick the service worker that has the firebase code.