DEV Community

loading...
This Dot

How To Add Notifications To Your PWA

Pato
Google Developer Expert on Angular and Web Technologies | Auth0 Ambassador | Media Developer Expert for Cloudinary | Twilio Champ | Technical Coach at SpringBoard | Google Women Techmaker
Originally published at labs.thisdot.co on ・4 min read

Have you ever wondered how to add those annoying (but useful) notifications to your progressive web app?

Well in this tutorial, I'm going to show you how!

What are we building?

pwa-sc1

pwa-sc2

Live Demo

https://pwa-notification-td.firebaseapp.com/

Before We Start

We will make use of the Notification API

Notification API: The Notification interface of the Notifications API is used to configure and display desktop notifications to the user. These notifications' appearances and specific functionalities vary across platforms but generally provide a way to asynchronously provide information to the user.

*Note: *The notification API is not the same as the Push API.

Time To Get Your Hands Dirty

1) Clone this repo:
https://github.com/devpato/pwa-notifications

2) You will see 3 folders. The ones that matter are the START and the FINAL folder. In the FINAL folder, you can see the final code but for the purpose of this tutorial, and for you to learn, just focus on the START folder.

3) Navigate to the main.js file inside of the scripts folder

4) Add the following code:

const notificationButton = document.getElementById('enableNotifications');
let swRegistration = null;
Enter fullscreen mode Exit fullscreen mode

The notificationButton is the button that will trigger the notification in our app. If you go to the index.html, you will see the button there that I've already created for you.

The swRegistration is just a global variable that will store our service worker.

Note: Notice the sw.js file is in the root folder. That's where service workers go, in the root.

5) Now let's create a function called initializeApp. This function will handle everything that needs to be triggered when the app first loads.

//First, we check if having service workers and notifications are //supported.
function initializeApp() {
  if ('serviceWorker' in navigator && 'PushManager' in window) {
    console.log('Service Worker and Push is supported');

    //Register the service worker
    navigator.serviceWorker
      .register('../../sw.js')
      .then(swReg => {
        console.log('Service Worker is registered', swReg);
        // We are storing the service worker, globally
        swRegistration = swReg;
      })
      .catch(error => {
        console.error('Service Worker Error', error);
      });
  } else {
    console.warn('Push messaging is not supported');
    notificationButton.textContent = 'Push Not Supported';
  }
}
Enter fullscreen mode Exit fullscreen mode

To learn more about the PushManger, visit : https://developer.mozilla.org/en-US/docs/Web/API/PushManager

6) When the app first loads, we need to call the initializeApp() function. To accomplish this - add the call before the declaration of the function itself.

7) Now we need to create a new function called initializeUi. This function will look as followed:

function initializeUi() {
  notificationButton.addEventListener('click', () => {
    //Do something here
  });
}
Enter fullscreen mode Exit fullscreen mode

The only purpose of this function is to attach a click event to the notificationButton. So when the user clicks on the button, something will happen.

8) Now inside of the initializeApp() (function we previously created), we invoke the initializeUi();, right after the swRegistration = swReg; expression:

function initializeApp() {
 ...
    navigator.serviceWorker
      .register('../../sw.js')
      .then(swReg => {
        ....
        // We are storing the service worker, globally
        swRegistration = swReg; 
        initializeUi();
      })
 ...
}
Enter fullscreen mode Exit fullscreen mode

By doing this, we will initialize the UI once the registration of the service worker has been successful.

9) Time to create a new function called displayNotification. The function will look like this:

function displayNotification() {
  //Ask user if we show notifications
  if (window.Notification && Notification.permission === 'granted') {
    //notification();
    // We will create this function in a further step.
  }
  // If the user hasn't told whether he wants to be notified or not
  // Note: because of Chrome, we cannot be sure the permission property
  // is set, therefore it's unsafe to check for the "default" value.
  else if (window.Notification && Notification.permission !== 'denied') {
    Notification.requestPermission(status => {
      if (status === 'granted') {
        //notification();
      } else {
        alert('You denied or dismissed permissions to notifications.');
      }
    });
  } else {
    // If the user refuses to get notified
    alert(
      'You denied permissions to notifications. Please go to your browser or phone setting to allow notifications.'
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

10) Go back to the initializeUi() inside of the click callback, where it says "Do something here". Replace that line with:

  displayNotification();
Enter fullscreen mode Exit fullscreen mode

Your code will look like this:

function initializeUi() {
  notificationButton.addEventListener('click', () => {
    displayNotification();
  });
}
Enter fullscreen mode Exit fullscreen mode

11) Finally, we are going to create a notification function that will contain the information we want to display in our notification.

function notification() {
  const options = {
    body: 'Testing Our Notification',
    icon: './bell.png'
  };
  swRegistration.showNotification('PWA Notification!', options);
}
Enter fullscreen mode Exit fullscreen mode

12) Inside of your displayNotification() function, you will see that we are calling the notification(), but it's commented out. Simply uncomment it so the code can be triggered.

13) The final code will look like this:
https://github.com/devpato/pwa-notifications/blob/master/final/scripts/main.js

14) Test the notification in your browser. If you want to test it on a real device, you need to deploy it and make sure that the deployed app gets served using https. You can you use firebase hosting for this.

Web Deployment with Firebase

As you might have noticed that we registered a service worker but we didn't add any code to it because it wasn't necessary. In the the next tutorial, we will actually be doing more with the service worker. In that tutorial, I will show you how to send push notifications from the server using Firebase Cloud Messaging. So, wait a bit and we'll explore much more about Service Worker features ;)

PWA Push Notifications with Firebase (Cloud Messaging)-pt1

Discussion (4)

Collapse
gktim profile image
gkTim

It really sucks that iOS isn‘t supporting Notifications for PWAs :/

Collapse
jamesrmoro profile image
James Moro

Hi!

If the user chooses to block the notification and, in the future, wants to activate it again? How do I change this permission? Let's say I did the conversion from PWA to TWA, where the url bar is not displayed, how do I change the permission status? For example: I want to have control of changing from denied to allowed through a button! Thanks!

Collapse
osde8info profile image
Clive Da

"...annoying (but useful)..." NO they are just annoying and can be disabled by the user anyway (see my post)