Firebase Messaging for Web app in React with Notification sound

When you have a web application and want your users to get a browser notification whenever the backend state changes it becomes a little tricky since you are no longer monitoring directly from the frontend.

In these cases, you can use the backend to trigger firebase messaging when an event occurs and use the below frontend configuration to receive notification both when the application is focused in the browser or the application browser tab is minimized/not focused.

Prerequisite

  • Install Firebase
npm i firebase
  • Get firebase configuration from your firebase app console:
{   
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
databaseURL: 'https://project-id.firebaseio.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
}
  • Generate a key pair(vapid key) to get token for messaging

Firebase Messaging in React App

Add service worker in react app- Background Messaging:
Why
: You need to add the firebase service worker in the react app to receive the background notification. Whenever your web application browser tab is not focused, firebase will use the background messaging function to trigger notifications.

In the public directory of the react app, add firebase-messaging-sw.js:

Note: Windows global object will not be accessible here.
Note: You don't have to manually register this service worker. It works in localhost as well- so you won't have trouble with testing.

importScripts('https://www.gstatic.com/firebasejs/9.2.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/9.2.0/firebase-messaging-compat.js');firebase.initializeApp({   
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
databaseURL: 'https://project-id.firebaseio.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
});
const messaging = firebase.messaging();messaging.onBackgroundMessage(function(payload) { //use BroadcastChannel for notification
const channel = new BroadcastChannel('notification_channel_name');
channel.postMessage({ key: payload });});

Set Foreground Messaging:

You can set the foreground messaging for the notification received when the web apps browser tab is focused.

You can configure foreground messaging in the component to which the notifications are related or in a component that loads when a user opens the app so the app can set the messaging token whenever the token is updated.

Foreground configuration: I set it in the routers component — App.js

import { initializeApp } from "firebase/app";
import { getMessaging, onMessage, getToken } from "firebase/messaging";
//Add this in relevant component
const app = initializeApp({
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
databaseURL: 'https://project-id.firebaseio.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
});
const messaging = getMessaging(app);//save firebase token locally
const FirebaseToken = localStorage?.FirebaseToken;
//notification permission
const getNotification = () => {
Notification.requestPermission();
if (!("Notification" in window)) {
} else {
Notification.requestPermission();
}
getFirebaseToken();//set token};const getFirebaseToken=()=>{
getToken(messaging, {
vapidKey:"YOUR_VAPID_KEY"
}).then((currentToken) => {
if (currentToken) {
if (FirebaseToken !== currentToken) {
localStorage.setItem("FirebaseToken", currentToken);
//also save the token in your apps backend to send the message to all those saved deviceIDs
}
}else {
getNotification();//ask for permission
}
}).catch((err) => {});
}//foreground message
onMessage(messaging, (payload) => {
if (payload) {
showNotification(payload);
}
});
//BroadcastChannel to recieve background messaging
const channel = new BroadcastChannel("notification_channel_name");
channel.onmessage = (event) => {
showNotification(event.data.key)
};
const showNotification=(body)=>{
if (body) {
//notification sound
let sound = new Audio(n5);
sound.play();
//notification body
const options = {
body: body.notification.body,
icon: "icon.png",
vibrate: true,//vibrate will work only on the mobile device
};
let notification = new Notification(body.notification.title, options);notification.onclick = function (event) {
event.preventDefault();
window.open("LINK_YOU_WANT_USER_TO_OPEN", "_blank");
};
}
}

Mostly you will see that developers are using the service workers' notification. The only thing wrong with it is that you won't be able to add sound to the notification.

If the notifications you are sending are important and need an immediate action of your user — You must add a notification sound which you will have to play independently as shown in the showNotification function.

What to do next

Make sure to delete the token on logout or just get a new firebase token and do not save it, this way when your app is closed/logged out the browser won't receive notifications.

--

--

--

Technical Writer, Software Developer, Blogger, and Career Development Coach…

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Map, flip(map) and partial application in JS

Things You Should Know When Starting a Career in Software Engineering

5 things you should know when you start your career in software engineering.

Web Development Bootcamp: Week 9

JavaScript Frameworks and Their Alter Egos in the Marvel Universe

WhatsApp Clone React Native — Part2

Making a resizable navbar when scrolling with jQuery

Using Font Awesome in Angular 2+

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Chanchala Gorale

Chanchala Gorale

Technical Writer, Software Developer, Blogger, and Career Development Coach…

More from Medium

Simplifying Authentication in React Apps with SawoLabs

Build A Login/Logout Demo with React and Firebase

Building a Todo App using React.js and Cloud Firestore

Firebase console

Custom Survey Engine using MongoDB Atlas & Realm