Using Firebase cloud messaging service worker with env in react js

40 Views Asked by At

I am trying to register a background web service from firebase cloud messaging to receive push notifications in my reactjs app.

The thing to note here is: in firebase-messaging-sw.js file, the config for firebase needs to be different based on the environment this project is in like: dev, staging or prod. Since I already have this info in my .env file in my reactjs project, I want to use it.

Since I cannot directly use values from .env inside public folder, I am doing the following although it's not working

#src/index.js


// register firebase push notification service worker with env variable
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/firebase-messaging-sw.js', {
    scope: '/'
  })
  .then(function(registration) {
    console.log('Registration successful, scope is:', registration.scope);
    // Pass environment variables to the service worker
    registration.active.postMessage({
      apiKey: process.env.REACT_APP_FIREBASE_ANALYTICS_API_KEY,
      authDomain: process.env.REACT_APP_FIREBASE_ANALYTICS_AUTH_DOMAIN,
      projectId: process.env.REACT_APP_FIREBASE_ANALYTICS_PROJECT_ID,
      storageBucket: process.env.REACT_APP_FIREBASE_ANALYTICS_STORAGE_BUCKET,
      messagingSenderId: process.env.REACT_APP_FIREBASE_ANALYTICS_MESSAGING_SENDER_ID,
      appId: process.env.REACT_APP_FIREBASE_ANALYTICS_APP_ID,
      measurementId: process.env.REACT_APP_FIREBASE_ANALYTICS_MEASUREMENT_ID,
    });
  })
  .catch(function(err) {
    console.log('Service worker registration failed, error:', err);
  });
}
#src/App.js


useEffect(() => {
    navigator.serviceWorker.ready.then(() => {
      generateCloudMessagingToken();
  
      if (Notification.permission === "granted") {
        onMessage(messaging, (payload) => {
          console.log("MESSAGING: ", payload);
          toast.success(payload.notification.title);
        });
      }
    });
  }, [Notification.permission]);

and finally, this is firebase-messaging-sw.js file:

// firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js');

self.addEventListener('message', (event) => {
  const {
    apiKey,
    authDomain,
    projectId,
    storageBucket,
    messagingSenderId,
    appId,
    measurementId
  } = event.data;

  firebase.initializeApp({
    apiKey: apiKey,
    authDomain: authDomain,
    projectId: projectId,
    storageBucket: storageBucket,
    messagingSenderId: messagingSenderId,
    appId: appId,
    measurementId: measurementId,
    // databaseURL: 'https://project-id.firebaseio.com', // Uncomment if needed
  });

  // Retrieve an instance of Firebase Messaging
  const messaging = firebase.messaging();

  // Listen for background messages
  messaging.onBackgroundMessage((payload) => {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);

    // Customize notification here
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
      body: payload.notification.body,
      icon: payload.notification.image
    };

    self.registration.showNotification(notificationTitle, notificationOptions);
  });
});

Maybe this might help. I am getting the following error in my browser after I allow notification permission:

Failed to execute 'subscribe' on 'PushManager': Subscription failed - no active Service Worker
    at getPushSubscription (http://localhost:3000/static/js/bundle.js:677620:37)
    at async getTokenInternal (http://localhost:3000/static/js/bundle.js:677537:28)
    at async generateCloudMessagingToken (http://localhost:3000/static/js/bundle.js:23462:19)
0

There are 0 best solutions below