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)