Web Push Notifications or Cloud Messaging using Firebase(FCM)

Recently I think almost everyone whoever using GCM for web push notifications got mail by saying Google has deprecated GCM and The GCM server and client APIs are deprecated and will be removed as soon as April 11, 2019. Migrate GCM apps to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure, plus many new features.

Our project delivers Web push notifications and that module is written long back by our ex-developer. So I started researching how FCM works and what to do at our end to deliver web push notification. Google has very good documentation. After reading this understood that this link/Documentation talking about proper Firebase integration rather than specific part(Cloud Messaging). Then I did little googling for example/demo project but didn’t get full details. I thought let’s do it by myself. Let’s start.

Before we start you need FCM server key, sender id & etc. For that, you need to create a project at https://console.firebase.google.com/

First, open this link. Click on Add Project. Then give a project name, select country and click on Create Project. For example, see the below image.

Now your project is created. Then click on continue. Then you will see something like below picture.

Now click on Settings icon which is next to Project Overview. Then click on Project Settings. Then you will get something like below picture.

Now click on CLOUD MESSAGING tab. This is important here you copy Server key, Sender ID. These 2 are required to proceed further.

Now, let’s start coding. To do this you can follow below steps or copy the code form my GitHub repository and follow the steps mentioned over there.

To run an application I am going to create a small Node.js application. I am assuming you Node.js & npm installed. If not please install them first. Create a directory and run below command.

npm init

It will ask several questions put as per your preference or else you can choose the default ones. We need web application so I am using express js framework. To install that package run below command.

npm install express --save

That’s it. You don’t need to install anything further. Now open app.js. If it’s not there just create one file with name app.js. Then paste this code.

var express = require('express');
var app = express();

app.use(express.static('public'));

app.get('/', function (req, res) {
    res.sendFile( __dirname + "/" + "index.html" );
})

var server = app.listen(8000, function () {
   var host = server.address().address
   var port = server.address().port
   console.log("App listening at http://%s:%s", host, port)
})

Nothing fancy here. I am just importing express. Then telling server that public folder has static files. Then telling server that display index.html when we hit application URL in the browser and listen at port 8000.

Now create firebase-messaging-sw.js at the public folder. The file name should be same because this is the convention for service worker according to Firebase. I hope you know about service worker if not please read this. Paste below code into
the service worker js file.

/*
Give the service worker access to Firebase Messaging.
Note that you can only use Firebase Messaging here, other Firebase libraries are not available in the service worker.
*/
importScripts('https://www.gstatic.com/firebasejs/4.13.0/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/4.13.0/firebase-messaging.js')

/*
Initialize the Firebase app in the service worker by passing in the messagingSenderId.
*/
firebase.initializeApp({
    'messagingSenderId': 'SENDER_ID'
})

/*
Retrieve an instance of Firebase Messaging so that it can handle background messages.
*/
const messaging = firebase.messaging()
messaging.setBackgroundMessageHandler(function (payload) {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);
    const notification = JSON.parse(payload.data.notification);
    // Customize notification here
    const notificationTitle = notification.title;
    const notificationOptions = {
        body: notification.body,
        icon: notification.icon
    };

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

In the place of SENDER_ID please put your sender id which we discussed above. Which present at CLOUD MESSAGING section in Firebase project. In above code also nothing fancy. Service worker importing Firebase dependency js files and then initialising firebase and messaging object created. Then we are setting background message handler. This message handler actually takes our web push notification and do the displaying work.

Now create index.html where our web page and user token capture code is there. Use below code for index.html.

<!DOCTYPE html>
<html>

<head>
    <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-messaging.js"></script>
    <script>
        firebase.initializeApp({
            'messagingSenderId': 'SENDER_ID'
        })
        const messaging = firebase.messaging();
        function initFirebaseMessagingRegistration() {
            messaging
                .requestPermission()
                .then(function () {
                    messageElement.innerHTML = "Got notification permission";
                    console.log("Got notification permission");
                    return messaging.getToken();
                })
                .then(function (token) {
                    // print the token on the HTML page
                    tokenElement.innerHTML = "Token is " + token;
                })
                .catch(function (err) {
                    errorElement.innerHTML = "Error: " + err;
                    console.log("Didn't get notification permission", err);
                });
        }
        messaging.onMessage(function (payload) {
            console.log("Message received. ", JSON.stringify(payload));
            notificationElement.innerHTML = notificationElement.innerHTML + " " + payload.data.notification;
        });
        messaging.onTokenRefresh(function () {
            messaging.getToken()
                .then(function (refreshedToken) {
                    console.log('Token refreshed.');
                    tokenElement.innerHTML = "Token is " + refreshedToken;
                }).catch(function (err) {
                    errorElement.innerHTML = "Error: " + err;
                    console.log('Unable to retrieve refreshed token ', err);
                });
        });
    </script>
</head>

<body>
    <h1>This is a test page</h1>
    <div id="token" style="color:lightblue"></div>
    <div id="message" style="color:lightblue"></div>
    <div id="notification" style="color:green"></div>
    <div id="error" style="color:red"></div>
    <script>
        messageElement = document.getElementById("message")
        tokenElement = document.getElementById("token")
        notificationElement = document.getElementById("notification")
        errorElement = document.getElementById("error")
    </script>
    <button onclick="initFirebaseMessagingRegistration()">Enable Firebase Messaging</button>

</html>

Here also don’t forget to replace SENDER_ID with your sender id. Here also nothing fancy. We are just importing the required Firebase js files then initialising firebase object and getting the messaging object. Then a method for asking user permission to send the push notifications and extracting user token. Then handlers for messaging and token refresh.

You might be wondered we already have one message handler in service worker then why we need one more message handler. Think about it if the user is browsing the site at that time we sent push notification it doesn’t look good at that time the messaging
hander which present in the index.html will take care.

If you want please put a logo in your public folder which will be shown at the time of push notification. That’s it. Everything set. It’s time for some action. Now you just need to open the command prompt and run below command.

node app.js

Open this link http://localhost:8000/. You will see below page

Click on Enable Firebase Messaging button. You will get prompt for show notifications permission. Click on Allow to watch the magic. Now you will get the token on the screen. Copy it

Now to send the push notification to your customer(for now it’s you) run this below command after replacing with your data.

curl -X POST -H "Authorization: key=SERVER_KEY" -H "Content-Type: application/json"    -d '{
  "data": {
    "notification": {
        "title": "FCM Message",
        "body": "This is an FCM Message",
        "icon": "/ab-logo.png",
    }
  },
  "to": "USER_TOKEN"
}' https://fcm.googleapis.com/fcm/send

Replace SERVER_KEY with the server key you got in Firebase project, Replace USER_TOKEN with the user token which you got on page after allowing show notifications. If possible replace the icon with the icon name you put in your code public folder.

That’s it. Congrats. You sent the push notification to your customer successfully.

Peace. Happy Coding.

Related Post

2 thoughts on “Web Push Notifications or Cloud Messaging using Firebase(FCM)

    1. Hi Tia,

      I didn’t understand your question. Can you please elaborate a bit.
      I have my site which I deployed in the server as a traditional NodeJS application. For that, I want to add web notifications functionality so I created a project at Firebase and used those key and other stuff at my site.

Leave a Reply to Tia Cancel reply

Your email address will not be published. Required fields are marked *