Implementing Firebase Push Notifications in a React App

Shehzad Ahmed
4 min readNov 22, 2023

--

Introduction

In the ever-evolving landscape of web development, integrating push notifications into your React application can significantly enhance user engagement. Firebase Cloud Messaging (FCM) provides a robust solution for handling push notifications, and when combined with React, it becomes a powerful tool for delivering real-time updates to your users.

In this article, we’ll walk through the process of setting up Firebase push notifications in a React app. We’ll cover Firebase initialization, creating a custom hook for monitoring visibility changes, handling notifications based on the app’s visibility status, and registering a service worker.

Prerequisites

Before we begin, make sure you have the following prerequisites:

  • Node.js and npm installed
  • A Firebase project with the necessary credentials
  • A basic understanding of React

Step 1: Set Up Firebase

Start by installing the required Firebase packages:

npm install @firebase/app @firebase/messaging

Create a firebase.js file for Firebase initialization and notification handling. The file should look like the following:

// firebase.js
import { initializeApp } from '@firebase/app';
import { getMessaging, getToken, onMessage } from '@firebase/messaging';

const firebaseConfig = {
// Your Firebase config here
};
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
const setupNotifications = async () => {
try {
// Request permission for notifications
const permission = await Notification.requestPermission();

if (permission === 'granted') {
console.log('Notification permission granted.');
// Get the FCM token
const token = await getToken(messaging);
console.log('FCM Token:', token);
} else {
console.log('Notification permission denied.');
}
// Handle foreground notifications
onMessage(messaging, (payload) => {
console.log('Foreground Message:', payload);
// Handle the notification or update your UI
});
} catch (error) {
console.error('Error setting up notifications:', error);
}
};
export { messaging, setupNotifications };

Step 2: Create a Custom Hook for Visibility Change

To determine whether your app is in the foreground or background, create a custom hook named useVisibilityChange. This hook will listen for visibility changes and update the app's visibility status accordingly:

// useVisibilityChange.js
import { useEffect, useState } from 'react';

const useVisibilityChange = () => {
const [isForeground, setIsForeground] = useState(true);
useEffect(() => {
const handleVisibilityChange = () => {
setIsForeground(document.visibilityState === 'visible');
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
return isForeground;
};
export default useVisibilityChange;

Step 3: Notification Helper Functions

Implement helper functions for displaying toast and native notifications. These functions will be called based on the app’s visibility status:

// notificationHelpers.js
export const toastNotification = ({ title, description, status }) => {
// Implement your toast notification logic
console.log(`Toast Notification: ${title} - ${description} - ${status}`);
};

export const sendNativeNotification = ({ title, body }) => {
// Implement your native notification logic
console.log(`Native Notification: ${title} - ${body}`);
};

Step 4: Create firebase-messaging-sw.js for Background Messages

Create a firebase-messaging-sw.js file at the public root of your React project. This file is required for handling background messages:

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

const firebaseConfig = {
// Your Firebase config here
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
// Customize background notification handling here
messaging.onBackgroundMessage((payload) => {
console.log('Background Message:', payload);
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
};
self.registration.showNotification(notificationTitle, notificationOptions);
});

Step 5: Register the Service Worker

Create a serviceWorker.js file for service worker registration:

// serviceWorker.js
export const register = () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/firebase-messaging-sw.js')
.then((registration) => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch((error) => {
console.error('Error registering service worker:', error);
});
}
};

Step 6: Integrate Everything into Your App

Update your App.js (or the main React component) to incorporate the Firebase setup, custom hook, and notification handling logic:

// App.js
import React, { useEffect } from 'react';
import { setupNotifications } from './firebase';
import { toastNotification, sendNativeNotification } from './notificationHelpers';
import useVisibilityChange from './useVisibilityChange';
import { register } from './serviceWorker';

function App() {
const isForeground = useVisibilityChange();
useEffect(() => {
setupNotifications((message) => {
if (isForeground) {
// App is in the foreground, show toast notification
toastNotification({
title,
description: body,
status: "info",
});
} else {
// App is in the background, show native notification
sendNativeNotification({
title,
body,
});
}
});
}, []);
return (
<div className="App">
{/* Your app content */}
</div>
);
}
export default App;

Step 7: Register Service Worker

Update your index.js to register the service worker

import React, { useEffect } from "react";
import ReactDOM from "react-dom/client";
import App from "./App"
import { register } from './serviceWorker';

root.render(
<App/>
);

register();

Conclusion

By following these steps, you’ve successfully integrated Firebase push notifications into your React app. You now have a setup that can show toast notifications when the app is in the foreground, native notifications when it’s in the background, and handles background messages using the firebase-messaging-sw.js file. This real-time communication will undoubtedly improve the user experience of your application.

Feel free to explore additional Firebase features and customize the notification handling logic to suit your specific use case. Happy coding!

Reference Links

  • Test FCM — A website to test Firebase Cloud Messaging (FCM) notifications.

Find me on your favorite platform

  • Github— Follow me on GitHub for further useful code snippets and open source repos.
  • LinkedIn Profile — Connect with me on LinkedIn for further discussions and updates.
  • Twitter (X) — Connect with me on Twitter (X) for useless tech tweets.

--

--

Responses (1)