Firebase Cloud Messaging in React: A Comprehensive Guide

Vanshita Shah
Simform Engineering
8 min readDec 6, 2023

Learn how to easily add push notifications to a React App using Firebase.

Firebase Cloud Messaging in React

Firebase is a popular web and mobile application development platform developed by Google that helps developers build, manage, and grow their apps easily. It offers various services for rapid app development and enhanced user experiences. Here are some important Firebase services:

  • Firebase Realtime Database
  • Firebase Authentication
  • Firebase Cloud Messaging (FCM)/ Firebase Push Notifications
  • Firebase Hosting
  • Firebase Cloud Firestore

In this article, we will explore the concept of Firebase Push Notifications in detail and also integrate this service into our React app for both background and foreground notifications.

What is FCM/Firebase Push Notifications?

Push Notifications are a powerful way of increasing user engagement with your React application. Firebase provides Firebase Cloud Messaging (FCM) service. It is a cloud-based messaging service that allows us to send notifications to mobile devices and web applications.

Leveraging FCM empowers you to alert a client app when there’s new stuff to check out. It’s like tapping your users on the shoulder, reminding them to come back and explore, keeping them hooked and happy.

Benefits of FCM :

  • Cross-Platform Support
  • Real-Time Engagement
  • Scalability and Reliability
  • User Segmentation
  • Easy Integration with Firebase Services
  • Free Tier Availability
  • Customization Options
  • Security Measures

For more info, click here.

Sample React app setup

  1. Initialize a Vite React project: Run the following command to create a new demo React app:
npm create vite@latest demo-app --template react
cd demo-app
npm install

2. Install dependencies: We will install firebaseand react-toastify. react-toastify allows you to add notifications to your app with ease.

npm i firebase react-toastify

3. Folder structure:

.
├── index.html
├── package.json
├── package-lock.json
├── public
│ ├── firebase-messaging-sw.js
│ └── vite.svg
├── README.md
├── src
│ ├── App.css
│ ├── App.jsx
│ ├── assets
│ │ └── react.svg
│ ├── components
│ │ └── Message.jsx
│ ├── firebase
│ │ └── firebaseConfig.js
│ ├── index.css
│ └── main.jsx
└── vite.config.js

Firebase project setup

1. Initialize a new Firebase project:

Add a new Firebase project and provide a name to it. Enable or disable analytics based on your preference.

Initializing firebase project
Firebase project initialization

2. Generate Firebase config :

We need to build a connection between the Firebase project and our React app. For that, we need Firebase config to integrate into our app.

Go to Project settings > General > Your apps . Select the web app option.

Provide a nickname and register the app. Config will be generated.

Firebase config

3. Generate web push certificate key(VAPID key):

VAPID stands for Voluntary Application Server Identity, a new way to send and receive website Push Notifications. With your VAPID key, your server can send web Push Notifications directly to browsers.

Go to Project settings > Cloud Messaging > Web configuration and generate a key pair.

VAPID key generation
VAPID public key

Connect React Application with Firebase Project

  1. Create environment variables:

Create a .env file in the root folder and store the Firebase config values and vapid key securely in that.

VITE_APP_API_KEY=your-api-key
VITE_APP_AUTH_DOMAIN=your-auth-domain
VITE_APP_PROJECT_ID=your-project-id
VITE_APP_STORAGE_BUCKET=your-storage-bucket
VITE_APP_MESSAGING_SENDER_ID=your-messaging-sender-id
VITE_APP_APP_ID=your-app-id
VITE_APP_MEASUREMENT_ID=your-measurement-id
VITE_APP_VAPID_KEY=your-vapid-key

You can import values from the .env file using:

import.meta.env.<VITE_APP_VARIABLE_NAME>

2. Create firebaseConfig.js:

Create a config file in src/firebase/firebaseConfig.js. Initialize the app and build a connection with the Firebase project using config.

To enable messaging service, we will have to use getMessaging provided by firebase/messaging. Connect the app with the messaging object.

import { initializeApp } from "firebase/app";

import { getMessaging } from "firebase/messaging";

//Firebase Config values imported from .env file
const firebaseConfig = {
apiKey: import.meta.env.VITE_APP_API_KEY,
authDomain: import.meta.env.VITE_APP_AUTH_DOMAIN,
projectId: import.meta.env.VITE_APP_PROJECT_ID,
storageBucket: import.meta.env.VITE_APP_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_APP_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_APP_APP_ID,
measurementId: import.meta.env.VITE_APP_MEASUREMENT_ID,
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

// Messaging service
export const messaging = getMessaging(app);

Notification permissions and registration token

In order to send Push Notifications to the browser, we need the user’s permission.

We will use the browser’s Notification API. We will ask for the user’s permission, and using the getToken method of Firebase and our messaging object, we can get our registration token.

In App.jsx, add the following code:

import { getToken } from "firebase/messaging";
import { messaging } from "./firebase/firebaseConfig";

const { VITE_APP_VAPID_KEY } = import.meta.env;

async function requestPermission() {
//requesting permission using Notification API
const permission = await Notification.requestPermission();

if (permission === "granted") {
const token = await getToken(messaging, {
vapidKey: VITE_APP_VAPID_KEY,
});

//We can send token to server
console.log("Token generated : ", token);
} else if (permission === "denied") {
//notifications are blocked
alert("You denied for the notification");
}
}

useEffect(() => {
requestPermission();
}, []);

In this scenario, we are currently displaying the token on the console. However, this token can also be transmitted to a server, allowing you to configure the backend using Node.js or any other suitable backend library.

Configuring notification listeners

Notifications can be of two types: foreground notifications and background notifications.

Every notification must have a title and body, the image is optional.

Foreground notification listener

To take care of cases in which the app is active in the foreground, we will be using the onMessage event listener from Firebase.

As mentioned earlier, handling of notifications is achieved through the utilization of react-toastify.

Ensure a seamless user experience by integrating the provided code in the App.jsx file.

import { toast, ToastContainer } from "react-toastify";
import Message from "./components/Message";
import "react-toastify/dist/ReactToastify.css";

function App() {

onMessage(messaging, (payload) => {
toast(<Message notification={payload.notification} />);
});

// ... Rest of the code ...
return (
<>
// ... Rest of the code ...
<ToastContainer />
</>
);
}

To display the notifications, created a separate component called Message.jsx as shown below:

const Message = ({ notification }) => {
return (
<>
<div id="notificationHeader">
{/* image is optional */}
{notification.image && (
<div id="imageContainer">
<img src={notification.image} width={100} />
</div>
)}
<span>{notification.title}</span>
</div>
<div id="notificationBody">{notification.body}</div>
</>
);
};

export default Message;

You can configure the style on your own, or you can use the style given below.

#notificationHeader {
display: flex;
justify-content: space-around;
align-items: center;
font-size: 20px;
font-weight: bold;
}

#notificationBody {
margin-top: 10px;
text-align: center;
}

#imageContainer {
display: flex;
align-items: center;
height: 100px;
object-fit: contain;
}

Background notification listener

To take care of cases in which the app is not active, we need to create a service worker file (firebase-messaging-sw.js) in the public folder. In that, we will be using the messaging.onBackgroundMessageevent listener.

This is an event listener that listens for incoming messages when the web application is not in the foreground (in the background or terminated). When a background message is received, it calls the provided callback function, which logs the message payload and displays a notification.

self.registration.showNotification is used to display a notification in the user's browser when a background message is received. It creates a notification with a title, body, and icon using the data from the FCM payload.

The code of firebase-messaging-sw.js is given below:

// Scripts for firebase and firebase messaging
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js");
importScripts(
"https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"
);

// Initialize the Firebase app in the service worker
// "Default" Firebase configuration (prevents errors)
const defaultConfig = {
apiKey: true,
projectId: true,
messagingSenderId: true,
appId: true,
};

firebase.initializeApp(firebaseConfig);

// Retrieve firebase messaging
const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.image,
};

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

Here, we have used the compact versions of the scripts importScripts which are V8 compatible.

Testing push notifications

We can now test whether our notifications service is working or not.

Go to Firebase> Engage> Messaging and click on create your first campaign. Select the message type as Firebase Notification messages and customize your notification message by providing a title, body, and image(optional).

Firebase notification customization

Click on send, and paste your registration token here. Select the token and click on test. The notification message will be sent.

test notification

Output

Foreground notification:

Here’s how the notification will look when the app is running in the foreground.

Output of foreground Notification
foreground notification

Background notification:

Here’s how the notification will look when the app is running in the background or terminated.

background notification

You can access the full source code using the following link: GitHub Repository 📌

Customization in notification campaign

We can configure many other things besides the notification title, body, and image.

  • Audience Targeting: Specify the target audience for your notification. You can target specific user segments based on various criteria, such as user languages, device categories, country/region, and more.
  • Scheduling: You can schedule when the notifications should be sent. You can send them immediately, at a specific time, or at recurring intervals.
  • Conversion Events: Conversion events are actions that you want users to take after receiving the notification. These actions might include clicking on the notification, making a purchase, signing up for a service, or any other user engagement metric that is valuable to your app. You can track these conversion events to measure the effectiveness of your notification campaigns.

Conclusion

This comprehensive guide has provided you with a step-by-step walkthrough for implementing push notifications in a React application. FCM is a cloud-based messaging service that empowers developers to send notifications. It offers cross-platform support and real-time engagement by notifying clients about new data availability. By following the outlined process, you must have successfully configured your app to deliver notifications in both foreground and background scenarios, ensuring real-time user engagement and re-engagement.

FCM can be a valuable resource for developers looking to enhance user engagement and notification delivery in their React applications.

For more updates on the latest tools and technologies, follow the Simform Engineering blog.

Follow Us: Twitter | LinkedIn

--

--