Using Push Notifications with Service Workers and Node.js

Using Push Notifications with Service Workers and Node.js

In this article, we cover another feature that we can implement with the help of Service Workers – Push Notifications.

They come in handy if we need a fast channel of communicating with our users. We not only learn how to implement them in terms of code, but we also explore the User Experience side of it.

Introducing Push Notifications

The history of web development contains a lot of different ways of displaying popup messages for the users of our page. We came a long way from using the window.alert() and we have many new possibilities. With Push Notifications, we can push them locally when our application is opened. We can also do it from the server, even if our application closes. To do that, in this article, we use Service Workers and a simple server written in Node.js.

When and how to ask for permission

Before showing any notifications, we need to ask for permission first. We do it outside of any Service Worker, in our regular JavaScript code.

if (window.Notification) {
  Notification.requestPermission((status) => {
    console.log('Status of the request:', status);
  });
}

The Notification.requestPermission now also returns a promise in browsers like Chrome and Firefox, but Safari uses only a callback
The code above opens a popup asking for permission. The choice of a user is stored so that he is not asked again. You can check out his decision in the Notification.permission parameter.

If the user changes his mind about notifications, he can easily change the settings by clicking an icon next to the address bar:

The big question in terms of User Experience is: should we ask our users for permissions right away? The chances are that when you find yourself in a situation like that, you instantly deny it. The above happens if we lack the context. Let the user know, why would you like to display some notifications for him.

Sometimes it might be obvious: for example when you are visiting some messaging application. Then, the user can safely guess that we want to notify him of any messages that he might receive.

Another example is an e-commerce application. Many users would consider notifications from a site like that to be just noise and spam if asked right away. On the other hand, if you display a permission popup when somebody makes a bid on an auction, the user might see some value in it and would want to be notified if he is not the highest bidder anymore. Remember that once someone denies permission to be presented with notifications, he needs to change it in the settings later explicitly: we can’t ask him again until then.

Sending Push Notifications locally

Once we got our permission, we can start displaying notifications. To do that, we need an active service worker.

index.js
if (window.Notification) {
  Notification.requestPermission(() => {
    if (Notification.permission === 'granted') {
      navigator.serviceWorker.register('./worker.js')
        .then((worker) => {
          worker.showNotification('Hello world!');
        });
    }
  });
}

For now, the worker.js file can be blank.> The navigator.serviceWorker.register('./worker.js') does not register a new worker, if it already exits.
And just like that, we’ve got our first notification! By default, the showNotification function displays a basic notification. You can pass some more arguments to it, for example, to display an icon. It can also make some sounds or vibrations, depending on the platform.

We can also do some more fancy things with our notifications, for example, we can attach click events to the notifications.

worker.js
self.addEventListener('notificationclick', () => {
  console.log('Clicked!');
});

Please note that this is inside of the worker.js file
One of the more interesting things that we can do is that we can define what buttons do we want on our notification popup. To do this, we use the actions property:

worker.showNotification('A new message!', {
  actions: [
    {
      action: 'show',
      title: 'Show it',
      icon: '/check.png'
    },
    {
      action: 'ignore',
      title: 'Ignore it',
      icon: '/delete.png'
    }
  ]
})

The design of the notification popup depends on the platform
We can check which button is clicked in the notificationclick event and react accordingly.

worker.js
self.addEventListener('notificationclick', (event) => {
  if (!event.action) {
    console.log('No button clicked');
    return;
  }
  switch (event.action) {
    case 'show':
      console.log('User wants to see more');
      break;
    case 'ignore':
      console.log('User wants to ignore the notification');
      break;
    default:
      console.log(`The ${event.action} action is unknown`);
      break;
  }
});

Sending Push Notifications from the server

In this article, to send push notifications, we use a Node.js server.

An essential thing to keep in mind is that the data needs to be encrypted. An excellent tool for that is the web-push library. To authenticate we need a public and a private VAPID key: the web-push library can generate it for us. Let’s make a separate application that is going to serve as our backend.

npm install web-push
./node_modules/web-push/src/cli.js generate-vapid-keys

You can also install the web-push library globall instead of running it from the node_modules
After running the commands above, we are presented with both the private and the public key. To place them in the env variables, we use the dotenv library.

npm install dotenv

If you would like to know more about env variables in Node.js, check out MongoDB, models and environment variables, that is a part of my Node.js Express series

require('dotenv/config');
const webpush = require('web-push');
 
const publicVapidKey = process.env.PUBLIC_VAPID_KEY;
const privateVapidKey = process.env.PRIVATE_VAPID_KEY;
 
webpush.setVapidDetails('mailto:[email protected]', publicVapidKey, privateVapidKey);

The first argument of the setVapidDetails function is called a subject. It provides a point of contact in case the push service needs to contact the sender.

Subscribing to the notifications

For our frontend to subscribe to the notifications, I’ll create an endpoint using Express.

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const webpush = require('web-push');
 
const app = express();
app.use(bodyParser.json());
app.use(cors({
  origin: 'http://localhost:8080'
}));
 
app.post('/subscribe', (req, res) => {
  const subscription = req.body;
  res.send(200);
 
  let i = 0;
  setInterval(() => {
    const payload = JSON.stringify({ title: `Hello!`, body: i++ });
    webpush.sendNotification(subscription, payload);
  }, 500);
});
 
app.listen(5000);

In this elementary example, I start spamming the user with multiple notifications for the sake of presentation.

Once the endpoint is ready, we can use it on the frontend.

<strong>index.js</strong>
const publicVapidKey = 'BEp878ZAJNHopeGksuSt5CtLL2iysV_uSskw7rvgbQIuqOC_UAlPEbbMLUtqfOdDi7ugqfeplwS7Is2dWJA7boc';

if (window.Notification) {
  Notification.requestPermission(() => {
    if (Notification.permission === 'granted') {
      getSubscriptionObject()
        .then(subscribe)
    }
  });
}

function getSubscriptionObject() {
  return navigator.serviceWorker.register('./worker.js')
    .then((worker) => {
      return worker.pushManager
        .subscribe({
          applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
        });
    });
}

In the function above we create a subscription object. We now need to send it to our endpoint.

function subscribe(subscription) {
  return fetch('http://localhost:5000/subscribe', {
    method: 'POST',
    body: JSON.stringify(subscription),
    headers: {
      'content-type': 'application/json'
    }
  });
}

Now the only thing left to do is to create the worker:

worker.js
self.addEventListener('push', event => {
  const data = event.data.json();
  self.registration.showNotification(data.title, {
    body: data.body,
  });
});

Every time we get the notification from the backend, the push event triggers. When that happens, we display the notifications.

The result

All of the code from above results in displaying multiple notifications, because the backend keeps sending them to us.

Even if we close the tab, the notifications keep coming, because they are independent.

Summary

In this article, we’ve covered Push Notifications. It included how and when to ask for permissions and how to display popups with notifications. Aside from that, we’ve also implemented a simple Node.js server that we can connect to and get notifications from. Thanks to that, we’ve learned yet another feature that Service Workers make possible.

Hire Node JS Developer from Expert Node JS Development Company

Hire Node JS Developer from Expert Node JS Development Company

NodeJS Development Company-Hire Node JS developer from the most prominent NodeJS development company, Mobiweb and get remarkable Node.js app development services.

Are you looking to hire the most talented and expert Node JS developers for your valuable web application projects and mobile app development projects or you want to migrate application on Node JS framework? Then you have to hire Node JS developer from leading offshore Node JS development company Mobiweb Technologies. We have a team of developers with extensive experience in developing Node JS based applications whether it is web based or mobile app based.

Web Development Services

Web Development Services

As one of the best Web Application Development Company, it provides a fine quality mobile app development service at an affordable price. Especially, it encourage start-ups that have unique ideas, by offering a more competitive price

HireFullStackDeveloperIndia is rated as one of the top Web Application Development Company in India by various industry magazines and review sites. They have a right blend of award-winning designers, expert programmers and Google certified digital marketers which make them a unique one-stop solution for hundreds of our clients, spread across all countries.

A Good website reflects not only your business but also it is one of the main factors why a potential customer would convert into Client. A good website design helps increase traffic driving leads to grow business. The best web design company create a custom design for each corporate website so as to help them meet their business goals.

Get Quote: https://hirefullstackdeveloperindia.com/get-a-quote/

Main Reasons of Using Node JS for Your Web Application Development

Main Reasons of Using Node JS for Your Web Application Development

You have to hire Node JS developer from prestigious and expert Node JS development company Mobiweb Technologies. They are tech enthusiasts with new and latest programming ideas, web development technologies and industry trends.

Node JS is the best JavaScript for utilizing in real-time applications. If you are stressed of using low level web sockets or protocols then with the incredible speed of Node JS you can easily develop real-time applications. According to the business perspective, Node JS is highly advantageous for any online business or business website, so it is very difficult for companies or business owners to avoid Node JS for their web application projects. For the best results in your Node JS development project you must have to hire Node JS developer from the prestigious web development company- Mobiweb Technologies.