Enhance Your React App with Firebase Push Notifications in TypeScript

Enhance Your React App with Firebase Push Notifications in TypeScript

Push notifications are a must-have feature for your website when you want to keep users in the loop about important events. You can show these notifications either when your website is open (foreground) or even when it's not the active tab in your browser (background). Firebase provides an awesome tool called Cloud Messaging to make this happen. In this blog, we’ll walk through how to add push notifications to a React app.

Getting Started

First, head over to the Firebase Console and create a new project. Once that's done, add a new app to your project by selecting the web option since we’ll be adding notifications to a website. After registering your app, you’ll see some code under "Add Firebase SDK"—go ahead and copy all that.

Setting Up Firebase in Your React App

Assuming you already have a React app set up, install the Firebase package with:

npm install firebase

Now, create a file called firebase.ts and paste the code you copied from Firebase. You’ll also need to import getMessaging from firebase/messaging and pass app to getMessaging. Here’s how your firebase.ts file should look:

// firebase.ts
import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging";

const firebaseConfig = {
  apiKey: "YOUR_VITE_FIREBASE_API_KEY",
  authDomain: "YOUR_VITE_FIREBASE_AUTH_DOMAIN",
  projectId: "YOUR_VITE_FIREBASE_PROJECT_ID",
  storageBucket: "YOUR_VITE_FIREBASE_STORAGE_BUCKET",
  messagingSenderId: "YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID",
  appId: "YOUR_VITE_FIREBASE_APP_ID",
};

export const app = initializeApp(firebaseConfig);
export const messaging = getMessaging(app);

Generating a FCM Token

To send notifications, you need a fcm token. Import getToken from firebase/messaging and create a function, say GenerateToken, in your firebase.ts file. Alternatively, you could make it in a separate file, just remember to export it. You can call this function in App.tsx so the token is generated when the website loads. Inside this function, request notification permission from the browser. If granted, call getToken, which takes messaging and vapidKey as arguments.

To get the vapidKey:

  1. Go to your project in Firebase Console.

  2. Click the settings gear next to "Project Overview" and choose "Project Settings."

  3. Click on "Cloud Messaging."

  4. Under "Web configuration," click "Generate key pair" to get your vapidKey.

Now use that key in getToken inside GenerateToken. Here's how it should look:

// firebase.ts

import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";

const firebaseConfig = {
  apiKey: "YOUR_VITE_FIREBASE_API_KEY",
  authDomain: "YOUR_VITE_FIREBASE_AUTH_DOMAIN",
  projectId: "YOUR_VITE_FIREBASE_PROJECT_ID",
  storageBucket: "YOUR_VITE_FIREBASE_STORAGE_BUCKET",
  messagingSenderId: "YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID",
  appId: "YOUR_VITE_FIREBASE_APP_ID",
};

export const app = initializeApp(firebaseConfig);
export const messaging = getMessaging(app);

export const GenerateToken = async () => {
  const permission = await Notification.requestPermission();
  if (permission === "granted") {
    const token = await getToken(messaging, {
      vapidKey: "YOUR_VITE_FIREBASE_VAPID_KEY",
    });
    console.log("Token generated", token);
  } else if (permission === "denied") {
    alert("User denied notification permission.");
    return;
  }
};

Setting Up the Service Worker

Create a file named firebase-messaging-sw.js inside your public folder. This file handles push notifications when your app is closed or minimized. Since you can’t import keys from .env files here, you’ll need to provide your keys directly or configure your build process to inject these keys. Here's what firebase-messaging-sw.js should look like:

// Import Firebase scripts
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 Firebase with your configuration
const firebaseConfig = {
  apiKey: "YOUR_VITE_FIREBASE_API_KEY",
  authDomain: "YOUR_VITE_FIREBASE_AUTH_DOMAIN",
  projectId: "YOUR_VITE_FIREBASE_PROJECT_ID",
  storageBucket: "YOUR_VITE_FIREBASE_STORAGE_BUCKET",
  messagingSenderId: "YOUR_VITE_FIREBASE_MESSAGING_SENDER_ID",
  appId: "YOUR_VITE_FIREBASE_APP_ID",
  vapidKey: "YOUR_VITE_FIREBASE_VAPID_KEY",
};

firebase.initializeApp(firebaseConfig);

// Retrieve an instance of Firebase Messaging
const messaging = firebase.messaging();

// Handle background messages
messaging.onBackgroundMessage((payload) => {
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
  };
  self.registration.showNotification(notificationTitle, notificationOptions);
});

Using the Token in Your App

Import GenerateToken in App.tsx and call it inside useEffect so the token is generated when your website loads. For showing notifications when the website is open (foreground notifications), import onMessage and messaging from firebase/messaging and firebase.ts, respectively. onMessage takes two arguments: messaging and a callback function.

Here's a simple example using react-hot-toast for notifications:

// App.tsx

import { onMessage } from "firebase/messaging";
import { useEffect } from "react";
import toast, { Toaster } from "react-hot-toast";
import "./App.css";
import { GenerateToken, messaging } from "./firebase";

function App() {
  // other codes

  useEffect(() => {
    GenerateToken();
    onMessage(messaging, (payload) => {
      toast(payload.notification?.body!);
    });
  }, []);

  return (
    <>
      {/* other code */}
      <Toaster />
    </>
  );
}

Testing Notifications

To test, console log the token and copy it. Then, follow these steps:

  1. In the Firebase Console, scroll down and click "See all Firebase features."

  2. Find and click on "Cloud Messaging."

  3. Click "Create your first campaign" > "Firebase Notification messages," then create.

  4. Fill out the form and click "Send test message."

  5. Paste the token where it says "Add an FCM registration token" and click the "+" sign.

  6. Click the "Test" button.

If your website is in the active tab, you’ll see a toast notification; otherwise, you’ll get a push notification. Make sure notifications are enabled in your system settings.

Adding push notifications to your React app using Firebase Cloud Messaging is a powerful way to keep your users engaged and informed. By following the steps outlined in this guide, you can seamlessly integrate this feature into your application, ensuring that users receive timely updates whether they are actively using your app or not. With Firebase's robust and easy-to-use tools, setting up push notifications becomes a straightforward process, enhancing the overall user experience and keeping your audience connected. Happy coding!