Another Step towards Progressive Web Application

Progressive Web App (PWA) is defining the future form of the web app. Google has predicted that PWA is going to replace a lot of mobile apps in the coming 2-3 years. It's not a surprise that the founder of Tapzo's summarized in his article The mobile app industry's worst-kept secret has reflected that lack of storage is the main reason 60-80% users are uninstalling the native mobile app within 90 days.

In comparison to web app, mobile app is able to access to the mobile native features like push notification, camera and others that the web app does not have. Well, the great news is, with the arrival of PWA, the web app is now finally able to access more native features.

Let's dive in to learn one of the very key benefit PWA is offering: engagement.

Push Notification In The Web App

Push notification has been one of the effective ways to improve retention rate and increase user engagement. The timely received push notification reminds users to react to online messaging, go to check out the cart before the offers and sales end, and even to notify users that their kingdom is under attacked by the enemy player so users can react before it's too late.

The magic of the push notification is that it allows the devices to get the update from the server without draining your battery. Once you have enabled the push notification, you can receive the alert even without visiting the website.

Example: How a Marketing Site keep us more engaged is one of the SEO marketing sites which has made good use of the push notification. Once you allow the site to send you notifications, you will see the pop-up notification first thing you open the Chrome browser, which shows you the newest blog from the site on the daily basis. This improves our engagement with the site by more than 50% than in the past.

Therefore, you need to have push notification for your web app. It is not that difficult to enable it, and we will show you the detailed step by step how to develop a push notification demo web app very shortly.

What's Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) is a service offered by Google to let you relay server messages to registered devices and web app. FCM service is free of charge with some limitations. The size is limited to 2KB or 4KB depending on the type of data, and the message will be kept for a default duration of 4 weeks before it gets deleted.

FCM offers an array of helpful tools to help you create the right engagements with users. You can create A/B testing to see what are the optimal wording and presentation to use. You can study the users' behaviour via the analytics data provided.

Firebase Predictions is the latest and perhaps the most exciting features added the to platform. Predictions apply Google's machine learning to your analytics data to predict the users' likely action based on users' behaviour.

For an example of a game app, a user who is likely to spend money to upgrade the game equipment, when he/she fail to pass the stage, the app will offer the option to let the user purchase more advanced equipment to continue the game. On the other hand, for free players, the app will trigger an advertisement to let the user watch to continue the game.

Besides FCM, you can also consider Amazon Simple Notification Service (SNS) and OneSignal. Both are also popular and used by a lot of developers. If you are keen to see how both services work, we can write another demo app next time.

Demo Tutorial

In the following, we will walk you through an easy to follow tutorial on how you can enable push notification using FCM. We will also share with you some of the small tips on what to take note of so you can have this up as quickly as possible.

Tutorial Step 1: Register Firebase account

Head to Firebase site and click "Go To Console". Once signed in you will see the following page. Click "Add Project" to create a new project. Give your project a name, and choose the country/region that reflects your currency and revenue reporting.

Firebase console page Firebase console page

 Tutorial Step 2: Getting your Project & Web App Credentials Info

(Updated: 23 Jul 2020) The recent Firebase's update requires the user to register the web app, as you will need the appId value. Give the web app a name, then click next and you will get your config like this. The config can be retrieved "Your apps" section in the Project Setting as well after you have created it. firebase-create-web

Now, Click on the cog icon beside the "Project Overview" at the top left > choose "Project Settings". Then click on "Cloud Messaging" on the settings page like below. Take note of the Server Key and Sender ID, you will need this later. You can ignore the "Legacy server key" and use "Server Key". Otherwise. you will face a problem when running the curl to test sending the notification.

Firebase Project Settings for Cloud MessagingFirebase Project Settings for Cloud Messaging

 Tutorial Step 3: Create the Simple HTML

Without further ado, let's start writing the simple HTML code. The page will show us the token and any message sent by the Firebase to us later.

<title>Firebase Messaging Demo</title>
    div {
        margin-bottom: 15px;
    <div id="token"></div>
    <div id="msg"></div>
    <div id="notis"></div>
    <div id="err"></div>
       MsgElem = document.getElementById("msg")
       TokenElem = document.getElementById("token")
       NotisElem = document.getElementById("notis")
       ErrElem = document.getElementById("err")

 Tutorial Step 4: Initialising Firebase and Creating Service Worker JS

Then you have to include the firebase.js. Remember to replace your "sender ID" as the value for messagingSenderId field. After that, you can initialise Firebase.

    var config = {
        messagingSenderId: "YOUR-SENDER-ID",
        apiKey: "YOUR_API_KEY",
        projectId: "YOUR_PROJECT_ID",
        appId: "YOUR_APP_ID"

Next, copy the following to firebase-messaging-sw.js and place it to the root of the web folder, this will create the service worker. (note on update for Firebase v7.0.0 and above)

// For an optimal experience using Cloud Messaging, also add the Firebase SDK for Analytics.

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
    messagingSenderId: "YOUR-SENDER-ID",
    apiKey: "YOUR_API_KEY",
    projectId: "YOUR_PROJECT_ID",
    appId: "YOUR_APP_ID",

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

messaging.setBackgroundMessageHandler(function(payload) {
        "[firebase-messaging-sw.js] Received background message ",
    // Customize notification here
    const notificationTitle = "Background Message Title";
    const notificationOptions = {
        body: "Background Message body.",
        icon: "/itwonders-web-logo.png",

    return self.registration.showNotification(

Without the file firebase-messaging-sw.js, you will get following error

; FirebaseError: Messaging: We are unable to register the default service worker. 
Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration).

Tutorial Step 5: Requesting permission from Device

We have to make a request explicitly to the user that we want to send him/her notification and get the permission from user to do so.

const messaging = firebase.messaging();
   .then(function () {
     MsgElem.innerHTML = "Notification permission granted." 
     console.log("Notification permission granted.");
   .catch(function (err) {
   ErrElem.innerHTML = ErrElem.innerHTML + "; " + err
   console.log("Unable to get permission to notify.", err);

If you start a local server and serve the code above, you will get the request prompt like the following screenshot.

Notification Request Prompt Notification Request Prompt

 Tutorial Step 6: Getting device token

After the user grant permission for us to send the notification, we can get an FCM registration token that can be used to send push messages to this user. For the sake of the simplicity of this demo app, we do not store the registration token in the database. We will modify the previous function to get the token and print it on the web page.

 const messaging = firebase.messaging();
   .then(function () {
     MsgElem.innerHTML = "Notification permission granted." 
     console.log("Notification permission granted.");

     // get the token in the form of promise
     return messaging.getToken()
   .then(function(token) {
     // print the token on the HTML page
     TokenElem.innerHTML = "Device token is : <br>" + token
   .catch(function (err) {
   ErrElem.innerHTML = ErrElem.innerHTML + "; " + err
   console.log("Unable to get permission to notify.", err);

Below is the screenshot you will see if you run the local server to check your code. The registration token (example: csxYa...jR4RI) is a long string of text. You will need this token for the next step.

Registration token after user grants the permission Registration token after user grants the permission

Tutorial Step 7: Test sending push message

By now, you are all set to send a push message to your web app! There are two ways to test sending message to the device.

A) Using Firebase Console

Go to Engage > Cloud Messaging, then click 'New Notification'.
Enter the title and text, then click on 'Send test message'.
Paste the device token you have gotten earlier, then click 'Test'. If everything is set up properly, you will see the push notification showing up.

B) Using Curl

Replace your API_ACCESS_KEY and the DEVICE_REGISTRATION_TOKEN we obtained just now. You can get your API_ACCESS_KEY by clicking on the "Authentication" under "Develop", then click on the "WEB SETUP" on the top right.

get Firebase API Access Key Firebase configuration options

To let your users immediately recognize the notification is from you, you can specify the icon for it.

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": "/itwonders-web-logo.png",

You will see the following response after successfully executing the curl command

success response after running curl command success response after running curl command

When your app is in the foreground, i.e. the user is currently viewing the web page, you can receive and notification directly on the page. For this example, we display the whole notification payload like in below

receive push notification when web app in the foreground Receiving notification when web app is in the foreground

However, if your app is in the background, the message received will trigger a display notification in the browser like the screenshot below. You can specify what action to perform if the user clicks on the notification as well. For example, to open the browser and load the site. Nevertheless, this behaviour can be changed.

push notification when app in background

 The Complete Solution

Here's the complete code based on what we have discussed so far. You can also get the source code from GitHub via this link.

If you are facing issue to get it running, you might also check with messaging example in Firebase quickstart-js. Official source code get updated quite frequently.

<title>Firebase Messaging Demo</title>
    div {
        margin-bottom: 15px;
    <div id="token"></div>
    <div id="msg"></div>
    <div id="notis"></div>
    <div id="err"></div>
    <script src=""></script>
    <script src=""></script>
        MsgElem = document.getElementById("msg");
        TokenElem = document.getElementById("token");
        NotisElem = document.getElementById("notis");
        ErrElem = document.getElementById("err");
        // Initialize Firebase
        // TODO: Replace with your project's customized code snippet
        var config = {
            'messagingSenderId': 'YOUR-SENDER-ID',
            'apiKey': 'YOUR_API_KEY',
            'projectId': 'YOUR_PROJECT_ID',
            'appId': 'YOUR_APP_ID',

        const messaging = firebase.messaging();
            .then(function () {
                MsgElem.innerHTML = "Notification permission granted." 
                console.log("Notification permission granted.");

                // get the token in the form of promise
                return messaging.getToken()
            .then(function(token) {
                TokenElem.innerHTML = "token is : " + token
            .catch(function (err) {
                ErrElem.innerHTML =  ErrElem.innerHTML + "; " + err
                console.log("Unable to get permission to notify.", err);




The End

If you are looking for a company to that is able to do website design and PWA you can consider us. We have years of experience in both UI/UX domain and the technical aspects of web.

That's all for now! Thanks for the reading and if you find this article helpful, do remember to like our Facebook and Twitter. Your comments will help us to do even better at next post. Cheers.

Sample Source Code: github


Change Log

26 Apr 2021 Github example update. Added description of how to send test message via Firebase Console.

23 Jul 2020 The Github example has been updated to user Firebase 7.16.1. There's some breaking change in the firebase-sw.js as well. So if you get a blank response or error, try to get updated the example source code again.

15 Mar 2020
There's some breaking change from the recent Firebase update on v7.0.0. Previously, having {messagingSenderId: 'xxx'} was sufficient config for firebase messaging, Now, all of these (apiKey, projectId, appId) are needed too. Otherwise, you will be getting an error.

[Messaging] FirebaseError: Installations:   
Missing App configuration values. (installations/missing-app-config-values)

Posted in Firebase, Google, Push Notifications, Tutorial, web development on Apr 26, 2021

Leave a comment or suggestion below


Godwin - January 26, 2018 @ 3:56 pm

What is curl? How can I enter the curl code? Where should I enter that curl code? I dont know.Please tell

xamDev - March 31, 2018 @ 6:23 am

create php file and put below curl code in it //script \"\n}"); curl_setopt($ch, CURLOPT_POST, 1); $headers = array(); $headers[] = "Authorization: key="; $headers[] = "Content-Type: application/json"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close ($ch); echo 'sent through'; ?> remember at Authorization: key you have to use Server key not API Key.

Vico - May 31, 2018 @ 8:12 am

cURL is a library and command line tool (see for basic informations). You just need to install the curl lib and then execute the above command in your console to execute it. It will send a POST request to FCM with the notification to send to the selected device.

Ken - June 13, 2018 @ 6:39 am

cURL stands for "client URL". cURL is a free and popular command line tool used to initiate request to server using various protocol, for example: POST, GET, PATCH and etc. In order to use cURL, you should either install it in window or it should be readily available in the Linux & Unix based OS. You can run the cURL tool in the terminal shell like "command prompt" in window or "Terminal" in Linux. Hope this helps.

frek - December 13, 2018 @ 4:34 pm

Can execute "sh" at the terminal

Truebred Labradors - April 11, 2018 @ 1:13 am

Thanks for the guide. I've been using PWA for a while now and wanted to now also include push notifications.

Bart - July 26, 2018 @ 3:05 pm

Notification permission granted. ; FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration). Is all i ever get. What's the serviceworker about?

charly arg - August 18, 2018 @ 4:58 pm

Same problem here wonder if something changed on Google's end..

Nagarajan M - August 28, 2018 @ 10:39 pm

all the files should be in root of the server, tried this on a subdirectory got same error, i was able to fix this after i moved all the files to root of the server

Subhash Diwakar - August 28, 2018 @ 11:27 am

Everytime i get this error Notification permission granted. ; FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration). How can I link firebase-messaging-sw.js to html

Ken Ng - October 31, 2018 @ 3:31 am

You do not have to link it, the firebase js done it for you. You just have to create this file and put to the root web folder of it. See the updated folder structure in the blog. See the github repo

Matias - February 18, 2020 @ 1:11 am

Donde pongo la ruta del sw.js en el html?

Ken Ng - March 15, 2020 @ 4:16 am

Hi Matias, please see the source code from Make use of the firebase-messaging-sw.js instead

Pawan - September 27, 2018 @ 7:58 am

Notification permission granted. ; FirebaseError: Messaging: This browser doesn't support the API's required to use the firebase SDK. (messaging/unsupported-browser).

Robert van Lienden - November 9, 2018 @ 12:04 pm

Realy thanks for this article! I'm struggeling for like a week with Push notifications. So much half working code on the internet, and so many puzzle pieces to connect. Your example is the first (!!) I get running in seconds, and understands in like a hour!

David - November 16, 2018 @ 12:12 pm

Thank you very much for being so clear in the explanations, may God bless you!

Sanjay - December 7, 2018 @ 11:44 am

Notification permission granted. ; FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html'). (messaging/failed-serviceworker-registration). Facing this issue , please help

Ken Ng - December 9, 2018 @ 5:26 am

Do you face any issue running github sourcecode? You might have missing file or wrong file type. Check to make sure you have firebase-messaging-sw.js at your root folder.

om vishnu - December 10, 2018 @ 10:46 am

good job for this blog

Yogender - December 14, 2018 @ 6:12 am

thankyou it works for me. i did this what how to display notification icon or alert. i am just only getting the response. which i have sent using curl.

Jaydeep Goswami - January 10, 2019 @ 12:39 pm

First of all thanks a lot brother for putting your great efforts and helping us. and next for all those who are getting confused in cURL Shell command or having no idea of command line interface than this is for those: Simply create a PHP file by any name like fire.php and copy the following code to send the notification. This will help you send the notification to the browser as shown in the above example : <?php $data = array(); $data['data']['notification']['title'] = "FCM Message"; $data['data']['notification']['body'] = "This is an FCM Message"; $data['data']['notification']['icon'] = "/itwonders-web-logo.png"; $data['data']['webpush']['headers']['Urgency'] = "high"; $data['to'] = "device-token-or-client-token-here"; // print_r(json_encode($data)); $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); $headers = array(); $headers[] = "Authorization: key = Your-server-key-here"; $headers[] = "Content-Type: application/json"; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_URL , ""); curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); curl_setopt($ch,CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch,CURLOPT_POSTFIELDS, json_encode($data)); // curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false); // curl_setopt($ch,CURLOPT_SSL_VERIFYPEER , false); $result = curl_exec($ch); if (curl_errno($ch)) echo 'Error:' . curl_error($ch); curl_close($ch); echo "<pre>Result : "; print_r(json_decode($result,1)); echo '<br>sent through</pre>'; ?> Note : don't forget to replace the DEVICE TOKEN & SERVER KEY values with your values. That's it! Now run this file in another tab and you can see the notification in the first tab. :)

mohini kandalkar - January 17, 2019 @ 9:56 am

after run this fire.php i got error Error:SSL certificate problem: unable to get local issuer certificate

Raman - April 23, 2019 @ 5:13 am

Thanks Jaydeep but when I run your code, the code in firebase-messaging-sw.js override it, and in notification - there are static values as defined in firebase-messsaging-sw.js file, please help

Mohammed Junaid - March 22, 2019 @ 11:32 am

{"multicast_id":7072924828349425332,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]} Getting this error on running Curl command

Rick - May 7, 2019 @ 2:56 pm

Hi Thanks for this tutorial.... Just a question: ¿Its posibble to set a push notification for Wordpress Multisite?... I mean, a differente service of Push Notifications for each site or subdomain? Some advice please?

Ken Ng - June 10, 2019 @ 6:03 am

Yes, just have to create different Firebase Project for each Wordpress subdomain and initialize the Wordpress based on the project setting.

suhel - June 1, 2019 @ 2:21 am

need help with send notification form rest is working fine

Marco - July 8, 2019 @ 11:21 am

Beautiful guide! I can get the notification out but I don't know how to change it. When I publish a new article, I would like a new notification to come out with the new article but I can't. How can I do? Thank you

Daniel LD - July 31, 2019 @ 7:36 am

Thanks a lot!! The tutorial is great! I only have one doubt, does this work on iOS?

Mayqui Quintana - September 5, 2019 @ 7:05 pm

Hi, I want could receive the push notification although the browser is not open.

Ken Ng - September 24, 2019 @ 4:14 am

likely not, as the push notification only pop up when the page is not active. it's just like when you are using whatsapp and someone send you a new message, it will just shown in the conversation box than as a push notification.

Charles Ram - September 17, 2019 @ 10:04 pm

Thank you! very nice explanation

Leo - October 1, 2019 @ 1:55 pm

Hello. How can I open the PWA when the user clicks the notification? Thanks

KIRUBAKARAN S - October 11, 2019 @ 11:48 am

Hi, Thanks for your post. I tried to implement. I am getting the Title and body as what we hard-coded in "firebase-messaging-sw.js". I dont know what i missed here. const notificationTitle = 'Background Message Title'; const notificationOptions = { body: 'Background Message body.', icon: '/itwonders-web-logo.png' }; But I was sending the below message from the curl. curl -X POST -H "Authorization: key=KEY" \ -H "Content-Type: application/json" \ -d '{ "data": { "notification": { "title": "FCM Message", "body": "This is an FCM Message", } }, "to": "TOKEN" }' Awaiting for your response.

Maulik - November 4, 2019 @ 6:59 am

Hello, Thank you so much for such a useful post. I tried to implement it as per your guidelines. I can get successfully FCM token and try to send a notification to send with CURL request using postman, I got a success response but can not receive notification in browser my browser is running. but when I tried to send notification from FCM console it's work.

Naveen - February 18, 2021 @ 7:19 am

how to send via fcm console. Please guid me

Marc - January 2, 2020 @ 10:51 pm

Many thanks for this tutorial. I have been seraching the web and testing code for days - without success. Your tutorial seem to be easy to understand, but unfortunaltely it does not work for me. I used all of your scripts and put in my data, but I never get that tiny box with the notification popping up at the right bottom of the screen. There was no error shown, but when I checked the developper console, the same script error was shown again and again: TypeError: Cannot destructure property 'title' of 'payload.notification' as it is undefined (probably referring to index.html: const {title, ...options} = payload.notification;) How can I make that work?

Ken - March 15, 2020 @ 3:44 am

Hi Marc, try to checkout the full source code in github on this link: If you have a working Firebase account and put in the correct configuration value to your code, it should be working.

Dwiky - July 8, 2020 @ 8:35 am

Same issues, i change to and solved the problem

Truepush - January 8, 2020 @ 11:47 am

Nice blog! Thanks a lot for such a great info!

santosh Patel - February 12, 2020 @ 10:33 am

Notification permission granted. ; FirebaseError: Installations: Missing App configuration values. (installations/missing-app-config-values).

Ken Ng - March 15, 2020 @ 4:06 am

hi santosh Patel, see the update on

kunal - February 26, 2020 @ 6:13 am

I am getting below error:- ; FirebaseError: Installations: Missing App configuration values. (installations/missing-app-config-values).

MushRoom - April 9, 2020 @ 1:32 am

Hi all, I did it. You all need to follow carefully step by step in tutorial and done ! About FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration). ==> You must have "firebase-messaging-sw.js" file and deploy project before test with link hosting firebase. Thanks a lot. Great tutorial.

prashanth - April 24, 2020 @ 11:11 am

Hi i got the token successfully but not get the curl how to do it can u say it i am trying in node.js

Sebram - April 27, 2020 @ 12:42 pm

Hello , i'm trying to do your tuto , very gool everything is ok ! it work fine, but i have a problem with clients.openWindow when i add that code , on push the is not displaying : self.addEventListener('notificationclick', function (event) { console.log('[Service Worker] Notification click Received.'); event.notification.close(); event.waitUntil( clients.openWindow('') ); }); do you have an idea? many thanks

salman saifi - June 22, 2020 @ 8:26 am

How to check notfication push or not through postman?

Zay Maung Maung Myint - July 13, 2020 @ 12:29 pm

I got token is null and there's no error in the console. Pls help to explain to me

Ken Ng - July 23, 2020 @ 2:35 am

Can check the updated source code again. It was breaks earlier due to Firebase update.

Fernando Jimenez - January 28, 2021 @ 11:43 pm

Hello guys, excellent article, I hope you can help me with a question. I have called the method to get the registration token successfully, but my question is, how do I send that token to my App Server? In many places I have read "send the token to the server" How? Maybe an API? I have an App Server developed with .net Core.

Ken Ng - April 25, 2021 @ 11:18 pm

Yap, you can send the token back to the server to store in a database. Typically user should have logged in, so you can associate it with the user.

Zeeshan Sheikh - February 12, 2021 @ 2:27 am

How to send the notifications to all tokens or users ?

Naveen Basati - February 18, 2021 @ 6:21 am

I am able to successfully generate the token and able to send the token to my curl php via ajax in the same page and getting success msg for fcm also. But still i am not getting any notification

Carlos Enrique Britez Rodriguez - March 23, 2021 @ 12:12 am

Hello! Nice tutorial? can i use an apache server with php with this example?

Ken Ng - April 25, 2021 @ 11:15 pm

This is only frontend code, you can integrate with any backend server

Dams - April 8, 2021 @ 8:44 am

Hi, It's good code, but when I send a message without the app open, I get the default message with Background Message Title and Background Message body. Do you have an idea ? Thank you

Dwij Virani - April 12, 2021 @ 11:02 am

How to run firebase-messaging-sw.js because when I try to run it using "node firebase-messaging-sw.js" then I get error "ReferenceError: importScripts is not defined"

Leave a Comment

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

About IT Wonders:

IT Wonders is a web agency based in Johor Bahru (JB), Malaysia and Singapore. We provide responsive and custom websites unique to your needs. If you have any inquiries about your website, do not hesitate to contact us.