Web push notifications are messages that appear on a user’s computer, tablet, or mobile device when they have an active web browser. Websites utilize web push to stay connected with visitors even after they have left their site, with the goal of enhancing user engagement, increasing conversions, and improving the digital experience. Web push is more convenient for users to enable and less likely to be ignored than conventional communication methods such as email.
In this blog, You will learn how you can setup a Firebase Project and integrate that with your react project to start receiving web notifications.
So lets start building the project.
React Project Setup
Lets create a new react app . Run the following command in your terminal to create a react app
npx create-react-app react-firebase-web-notifications --template typescript
cd react-firebase-web-notifications
npm run start
Create a page to receive notifications
After creating the project with the initial codebase, we have the src/App.tsx
file for the main page. Lets modify this page according to our need Firebase Project Setup
import React, { useState } from "react";
import "./App.css";
function App() {
const logo = require("./assets/sun.gif");
const [open, setOpen] = useState(false);
return (
Web Push Notifications with react and firebase
{open && (
{
setOpen(false);
}}
>
New Message
Hello Welcome, Today you will learn how to use firebase-notifications
)}
);
}
export default App;
after you are done writing this code,Run the project and you will get to see this page.

Firebase Project Setup
- If you don’t already have an app at Firebase yet, you should create one.
- After successfully creating an account, you will be redirected to Firebase Console where you can create a project by clicking the Create a project button and follow the on screen instructions.

- 3. After you have a Firebase project, you can register your web app with that project.
If you have created a project before, you will have a list of project cards. In this case, you need to click Add project
to create a new one.

Once you click Add Project, You will directed to this page , where you have to provide name for your project, I will be naming it firebase-web-notifications
. You can provide any name you want and click on continue.

In this page you can either opt-in for the Google analytics or Opt-out.

Hurray, Congrats There you go, Now you have successfully created your Firebase project.

Lets integrate firebase to our react app. Click on the Web icon </> to add firebase to the project. Upon clicking you will be prompted to this page.
Provide any nickname you want, i will be providing firebase-web-notifications
, then click on register app

Here you will be provided with the firebase configs which are essential to integrate your web-app with react project, Copy the configs object and keep it in a file for future use.

Integration Of Firebase Messaging With React App
Lets install firebase in your react app for receiving notifications. Run the below given command in the terminal of the root of your project
npm install dotenv
Step 1 . Securing Firebase Configs
Now in order to use the firebase configs you got in a secure way, we make use of dotenv
package. You can install it using the following the command
npm install dotenv
after successfully installing the package. create a file named .env
in the src folder of your project.In that file add the configs you got in the below mentioned manner.
REACT_APP_FB_API_KEY='API key'
REACT_APP_FB_AUTH_DOMAIN='Auth domain'
REACT_APP_FB_PROJECT_ID='Project id'
REACT_APP_FB_STORAGE_BUCKET='Storage bucket'
REACT_APP_FB_MESSAGIN_SENDER_ID='Messaging id'
REACT_APP_FB_APP_ID='App id'
REACT_APP_FB_VAPID_KEY='Vapid key'
if you notice the above lines, you will see a field named REACT_APP_FB_VAPID_KEY
, you can get this key from Project setting
Project overview > Project settings > Cloud Messaging > Web Configuration > Generate key pair. Upon clicking Generate key pair
. You will get a key, Then add that key to your REACT_APP_FB_VAPID_KEY
field in .env
file.

Step 2 . Creating a service-worker
Lets create a file called FirebaseConfig.tsx
to initialize firebaseapp by using the firebase configs that we stored in the .env
file.
Here, we will generate a service worker that operates in the browser’s background without requiring user intervention, which we will use to handle push notifications. Currently, we do not possess a service worker. So lets create one.
import { initializeApp } from "firebase/app";
import { getToken, getMessaging, isSupported } from "firebase/messaging";
const firebaseConfig = {
apiKey: process.env.REACT_APP_FB_API_KEY,
authDomain: process.env.REACT_APP_FB_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FB_PROJECT_ID,
storageBucket: process.env.REACT_APP_FB_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FB_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FB_APP_ID,
};
export const firebaseApp = initializeApp(firebaseConfig);
export const messaging = getMessaging(firebaseApp);
// getOrRegisterServiceWorker function is used to try and get the service worker if it exists, otherwise it will register a new one.
export const getOrRegisterServiceWorker = () => {
if (
"serviceWorker" in navigator &&
typeof window.navigator.serviceWorker !== "undefined"
) {
return window.navigator.serviceWorker
.getRegistration("/firebase-push-notification-scope")
.then((serviceWorker) => {
if (serviceWorker) return serviceWorker;
return window.navigator.serviceWorker.register(
"/firebase-messaging-sw.js",
{
scope: "/firebase-push-notification-scope",
}
);
});
}
throw new Error("The browser doesn`t support service worker.");
};
// getFirebaseToken function generates the FCM token
export const getFirebaseToken = async () => {
try {
const messagingResolve = await messaging;
if (messagingResolve) {
return getOrRegisterServiceWorker().then((serviceWorkerRegistration) => {
return Promise.resolve(
getToken(messagingResolve, {
vapidKey: process.env.REACT_APP_FB_VAPID_KEY,
serviceWorkerRegistration,
})
);
});
}
} catch (error) {
console.log("An error occurred while retrieving token. ", error);
}
};
Now your React app is capable of receiving notifications, But it wont visible to the user , Hence in the next step lets modify our App.tsx to display these notifications.
Step 3 . Show notifications on web in foreground
Add the following code to your existing App.tsx file in-order to display the notifications.
/* eslint-disable jsx-a11y/anchor-is-valid */
import { MessagePayload, onMessage } from "firebase/messaging";
import React, { useEffect, useState } from "react";
import "./App.css";
import { getFirebaseToken, messaging } from "./FirebaseConfig";
interface NotificationPayloadProps {
data?: MessagePayload | undefined;
open: boolean;
}
function App() {
const logo = require("./assets/sun.gif");
const [open, setOpen] = useState(false);
// To store notification data from firebase
const [notificationPayload, setNotificationPayload] = useState<
(NotificationPayloadProps | undefined)[]
>([]);
// This is self invoking function that listen of the notification
const onMessageListener = (async () => {
const messagingResolve = await messaging;
if (messagingResolve) {
onMessage(messagingResolve, (payload: MessagePayload) => {
setNotificationPayload([{ data: payload, open: true }]);
setTimeout(() => setNotificationPayload([{ open: false }]), 6000);
});
}
})();
const handleGetFirebaseToken = () => {
getFirebaseToken().then((firebaseToken: string | undefined) => {
if (firebaseToken) {
console.log(firebaseToken);
}
});
};
// Need this handle FCM token generation when a user manually blocks or allows notification
useEffect(() => {
if (
window.Notification?.permission === "granted"
) {
handleGetFirebaseToken();
}
}, []);
return (
{/* Used to notify user whether he has provided notification permissions or not */}
{Notification.permission !== "granted" && (
The app needs permission to
enable push notifications.
)}
Web Push Notifications With React And Firebase
{/* Rendering Notification from firebase */}
{notificationPayload.map((notification) => {
return (
<>
{notification?.open && (
{notification?.data?.notification?.title}
{notification?.data?.notification?.body}
)}
>
);
})}
{/* Rendering Demo Notification */}
{open && (
{
setOpen(false);
}}
>
New Message
Hello Welcome, Today you will learn how to use
firebase-notifications
)}
);
}
export default App;
Now you can successfully display notifications that you get from firebase.
You can access the FCM Token that is generated using the console now.

Step 4. Show notifications on web in background
To Display your notifications in the background, You need to create a service-worker file in your public folder called firebase-messaging-sw.js
and add your firebase configs and Background message handler.
Since the file in the public folder can be accessed by anyone, we need to securely insert our firebase configs in that file. for that we make use of URLSearchParams
. So lets add the below mentioned code inside our FirebaseConfig.tsx
const UrlFirebaseConfig = new URLSearchParams(
{
apiKey: process.env.REACT_APP_FB_API_KEY,
authDomain: process.env.REACT_APP_FB_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FB_PROJECT_ID,
storageBucket: process.env.REACT_APP_FB_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FB_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FB_APP_ID,
}.toString()
);
const swUrl = `http://localhost:3000/firebase-messaging-sw.js?${UrlFirebaseConfig}`;
Now in firebase-messaging-sw.js
file add the following code to access the firebase configs and also to add a background message handler
/* eslint-disable no-restricted-globals */
/* eslint-disable no-undef */
// required to setup background notification handler when browser is not in focus or in background and
// In order to receive the onMessage event, app must define the Firebase messaging service worker
importScripts('https://www.gstatic.com/firebasejs/9.15.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.15.0/firebase-messaging-compat.js');
// Set Firebase configuration, once available
self.addEventListener('fetch', () => {
try {
const urlParams = new URLSearchParams(location.search);
self.firebaseConfig = Object.fromEntries(urlParams);
} catch (err) {
console.error('Failed to add event listener', err);
}
});
// "Default" Firebase configuration (prevents errors)
const defaultConfig = {
apiKey: true,
projectId: true,
messagingSenderId: true,
appId: true,
};
// Initialize Firebase app
firebase.initializeApp(self.firebaseConfig || defaultConfig);
let messaging;
try {
messaging = firebase.messaging();
} catch (err) {
console.error('Failed to initialize Firebase Messaging', err);
}
// To dispaly background notifications
if (messaging) {
try {
messaging.onBackgroundMessage((payload) => {
console.log('Received background message: ', payload);
const notificationTitle = payload.notification.title;
const notificationOptions = { body: payload.notification.body };
self.registration.showNotification(notificationTitle, notificationOptions);
});
} catch (err) {
console.log(err);
}
}
Now your app is capable of handling notifications in background as well as foreground. There is only one thing that is left, Lets see about that in the next section.
Handling Errors When Working With Safari Or iOS
1. Push API not supported in Safari and iOS Safari
As Push API
doesn’t support on Safari, so your firebase web notification config will fail and will return an error or blank page.

So in order to avoid this we make use of a function called isSupported(). This function Checks if all required APIs exist in the browser. using this you need to initialize messaging only if isSupported
is true.
So lets modify our FirebaseConfig.tsx
file to add check. Obtain the firebaseapp inside messaging only when isSupported
is true
export const messaging = (async () => {
try {
const isSupportedBrowser = await isSupported();
if (isSupportedBrowser) {
return getMessaging(firebaseApp);
}
console.log("Firebase is not supported in this browser");
return null;
} catch (err) {
console.log(err);
return null;
}
})();
This will prevent the firebase crash in your safari or iOS safari browsers.
2. Notification is undefined
In this project , we are making use of Notification API of window interface to check whether Notification permission is granted or not, Since Push API is not supported on Safari this will result in crash of your app.
So in order to avoid this, we need to add few checks wherever we are making use of Notification.permission
. So we will modify our App.tsx to include this change.
useEffect in the App.tsx
will be
useEffect(() => {
if (
"Notification" in window &&
window.Notification?.permission === "granted"
) {
handleGetFirebaseToken();
}
}, []);
and UI which renders the Permission Banner will include this check
{"Notification" in window && Notification.permission !== "granted" && (
The app needs permission to
enable push notifications.
)}
Yeah, That’s it. You are all set with Web Push Notification using Firebase.
Testing The Firebase Notifications
You can make use of Firebase Console > Engage > Messaging > Create your first campaign
test out the notifications. Enter your notification title and and text , Then click on send test message
and add FCM token that you got in the console of your react app.

Thank you. Happy Coding
You can find the the complete project on Github.