{{announcement.body}}
{{announcement.title}}

Adding Push-Notification to a React Web App With Firebase Cloud Messaging

DZone 's Guide to

Adding Push-Notification to a React Web App With Firebase Cloud Messaging

Learn how to use Firebase to add push notifications to your React.js web application, and use Postman to test it out.

· Web Dev Zone ·
Free Resource

We will create an MVP of an app on React that will receive push notifications by using Firebase Cloud Messaging (even in the background mode or when the app is closed). This is an easy thing to do but there are certain moments to watch for. You can find all the needed keys/tokens described below in the Firebase settings of the project.

Adding manifest.json

Add a manifest.json file to the folder that already has an index.html file with  gcm_sender_id. If you already have the manifesto, simply add this line. Insert the value below as is, without changing anything.

{
	"gcm_sender_id": "103953800507"
}

Connect the manifesto in the index.html file; your href may differ.

<head>
	<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
</head>

To make sure that everything is working correctly we need to open the browser's dev tools panel and navigate to the Network tab, be sure that manifest.json was loaded by your application and it contains gcm_sender_id .

Image title

Setting Up a Service Worker for Receiving Messages

Create a public/firebase-messaging-sw.js file. This is a future service worker that will receive the messages in background mode. setBackgroundMessageHandler is responsible for that. In the piece of code below you can see the event handler by a click on the tooltip message  ...addEventListener('notificationclick...  if the tab is not active or closed.

importScripts("https://www.gstatic.com/firebasejs/5.9.4/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/5.9.4/firebase-messaging.js");

firebase.initializeApp({
// Project Settings => Add Firebase to your web app
  messagingSenderId: "1062407524656"
});

const messaging = firebase.messaging();

messaging.setBackgroundMessageHandler(function(payload) {
  const promiseChain = clients
    .matchAll({
      type: "window",
      includeUncontrolled: true
    })
    .then(windowClients => {
      for (let i = 0; i < windowClients.length; i++) {
        const windowClient = windowClients[i];
        windowClient.postMessage(payload);
      }
    })
    .then(() => {
      return registration.showNotification("my notification title");
    });
  return promiseChain;
});

self.addEventListener('notificationclick', function(event) {
  // do what you want
  // ...
});

In order for the worker to start working, you have to register it from the beginning. I did it right before the app's entry point. The official documentation suggests you register the FCM worker in a slightly different way, but, depending on the Webpack settings, you may get an incorrect mime-type error upon uploading the worker. Below is the most reliable method in, my opinion.

import ReactDOM from "react-dom";
import App from "./App";

if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("./firebase-messaging-sw.js")
    .then(function(registration) {
      console.log("Registration successful, scope is:", registration.scope);
    })
    .catch(function(err) {
      console.log("Service worker registration failed, error:", err);
    });
}

ReactDOM.render(, document.getElementById("root"));

Ensure that the worker loaded with no errors. 

Image title

And that the browser registered it. 

Image title

Check the browser console for any manifesto or service worker errors and fix them, if there are any.

Setting Up the Firebase SDK

yarn add firebase
# or
npm install firebase

Connecting Firebase Cloud Messaging

Create a  src/init-fcm.js  file where you will initialize the FCM. In the comments below you can see where to get the keys.

import * as firebase from "firebase/app";
import "firebase/messaging";

const initializedFirebaseApp = firebase.initializeApp({
// Project Settings => Add Firebase to your web app
  messagingSenderId: "106240...4524656"
});

const messaging = initializedFirebaseApp.messaging();

messaging.usePublicVapidKey(
// Project Settings => Cloud Messaging => Web Push certificates
  "BD6n7ebJqtOxaBS8M7xtBwSxgeZwX1gdS...6HkTM-cpLm8007IAzz...QoIajea2WnP8rP-ytiqlsj4AcNNeQcbes"
);

export { messaging };

Now connect everything that you did to a React component. The most important actions here take place in the lifecycle method componentDidMount. Remember that it’s an MVP and, in a real project, you can allocate everything to different places. 

// ...
import { messaging } from "./init-fcm";

// ...
async componentDidMount() {
  messaging.requestPermission()
    .then(async function() {
const token = await messaging.getToken();
    })
    .catch(function(err) {
      console.log("Unable to get permission to notify.", err);
    });

  navigator.serviceWorker.addEventListener("message", (message) => console.log(message));
}

In order for the service to start sending us messages, we should let it know the address of our app. For that, we need to get a token and pass it to the server. With the help of this token, the server will know the address through which we registered.

To get the token, we have to allow the browser to receive push messages. In this case, messaging..requestPermission() will show the following on the loading page: 

Image title

You can always change this configuration: 

Image title

Only after the permission described above, messaging.getToken() can get the token.

In order to receive the messages, we have to install the handler on onMessage. The official documentation suggests the following method:

messaging.onMessage((payload) => console.log('Message received. ', payload));

This method works only if the tab with the app is in focus. We will put the handler right on the client in the service worker. Depending on the tab focus, message will have a different structure.

navigator.serviceWorker.addEventListener("message", (message) => console.log(message));

If you are a bit confused by now, check out Set up a JavaScript Firebase Cloud Messaging client app - official documentation with a step-by-step guide. It describes the logic of token update very well. We will skip it, though, so the article doesn't get too long. 

Sending and Receiving Messages

We will use Postman for that.

1. Set up the query titles. Authorization title in the form key= . The key for the sender (server) is in the project settings Settings ⇒ Cloud Messaging ⇒ Server key

Postman

2. Setting up the query body Postman

In the  "to:" field, use the previously obtained token from  messaging.getToken(). For data transfer, we will use the "data" field that can have any nesting. As well, check out the official documentation on writing the query structure. There are a few query types and browsers proceed them differently. In my opinion, the  "data"  query is the most universal one. Then simply click the Send button and in the browser, receive the previously sent information.

The End

The code in this article serves for demonstration purposes. The project is here ⇒  react-fcm . Don’t forget to insert the keys from your project before starting.

Topics:
firebase ,push notification ,web dev ,react.js tutorial ,javascript tutorial for beginners ,postman

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}