Push Notifications, the Core Technology of Progressive Web Apps(PWA)

Keywords: Attribute network Android Database

PWA push is based on Notifications API and Push API. Notifications API allows applications to display system notifications to users. The Push API allows service worker s to process push messages from servers, even if the application is inactive.

Terminology of push notification

  • Notification - Messages that are displayed to users outside the normal user interface (browser) of the application.
  • Push message - message sent from server to client
  • Push Notification - Notification created in response to push messages
  • Notification API - Interface for configuring and displaying notifications to users
  • Push API - An interface for subscribing your application to push services and receiving push messages among service personnel
  • Web Push - An informal term referring to the processes or components involved in pushing messages from servers to clients on the network
  • Push Service - A system that routes push messages from the server to the client. Each browser implements its own push service
  • Web Push Protocol - Describes how application servers or user agents interact with push services

Notify API

Notification API has two core parts
1. Invocation API* controls how to display your notifications, including style and vibration.
2. Interaction API* controls what happens when users use notifications.

Because the compatibility of browsers is inconsistent, we need to check whether the browsers support and have permissions before using them.

//Check for support
if ('Notification' in window && navigator.serviceWorker) {
  // Display the UI to let the user toggle notifications
}
//Check authority
if (Notification.permission === "granted") { 
  /* do our magic */
} else if (Notification.permission === "blocked") {
 //Users refuse to push 
} else {
  //Display hint
}

Notification code should be written to the main JS file, such as main.js.

Request notification authority

Notification.requestPermission(function(status) {
    console.log('Notification permission status:', status);
});

Display notification
Note that the showNotification method is called on the service worker registration object. This creates notifications on the service worker so that the service worker can listen for events triggered by the notification interaction.

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      reg.showNotification('Hello world!');
    });
  }
}

Add notification options

Complete Options Introduction:
https://developer.mozilla.org/enUS/docs/Web/API/ServiceWorkerRegistration/showNotification
Online effect display:
https://tests.peter.sh/notification-generator/

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      var options = {
        body: 'Here is a notification body!',//Main content
        icon: 'images/example.png',//Notification icon
        vibrate: [100, 50, 100],//Vibration, first 100 ms, then pause 50 ms and finally 100 ms
        data: {//Notification data for human-computer interaction
          dateOfArrival: Date.now(),
          primaryKey: 1
        }
      };
      reg.showNotification('Hello world!', options);
    });
  }
}

Adding events to notifications

function displayNotification() {
  if (Notification.permission == 'granted') {
    navigator.serviceWorker.getRegistration().then(function(reg) {
      var options = {
        body: 'Here is a notification body!',
        icon: 'images/example.png',
        vibrate: [100, 50, 100],
        data: {
          dateOfArrival: Date.now(),
          primaryKey: 1
        },
        actions: [//Event Button List to listen for click events of these buttons
          {action: 'explore', title: 'Explore this new world',
            icon: 'images/checkmark.png'},
          {action: 'close', title: 'Close notification',
            icon: 'images/xmark.png'},
        ]
      };
      reg.showNotification('Hello world!', options);
    });
  }
}

Monitoring events
Monitoring events in service worker. JS

//Listen for shutdown notification events, such as sliding notification shutdown on Android.
self.addEventListener('notificationclose', function(e) {
  var notification = e.notification;
  var primaryKey = notification.data.primaryKey;

  console.log('Closed notification: ' + primaryKey);
});

//Click events to listen for notifications
self.addEventListener('notificationclick', function(e) {
  var notification = e.notification;
  var primaryKey = notification.data.primaryKey;
  var action = e.action;

  if (action === 'close') {
    notification.close();
  } else {
    clients.openWindow('http://www.example.com');
    notification.close();
  }
});

Push API

Notification and delivery are different, but they are complementary. Push is when the server pushes the message to the service worker, and the notification is when the service worker presents the message to the user.

Network push involves client management and server management. We focus on the client side of Web push because it involves push notifications (Push API s). We will give the details of the server side to the three-party providers, such as firebase.

Working Principle of web Push
Let's see how Web push works.

Each browser pushes notifications through its own system management, known as "push services". When a user grants push privileges to your website, you can subscribe to the application to the browser's push service. This creates a special subscription object that contains the "endpoint URL" (different for each browser) and public key of the push service. You send the push message to this URL, encrypt it with the public key, and send it to the correct client by the push service.
As follows:

{"endpoint":"https://fcm.googleapis.com/fcm/send/dpH5lCsTSSM:APA91bHqjZxM0VImWWqDRN7U0a3AycjUf4O-byuxb_wJsKRaKvV_iKw56s16ekq6FUqoCF7k2nICUpd8fHPxVTgqLunFeVeB9lLCQZyohyAztTH8ZQL9WCxKpA6dvTG_TUIhQUFq_n",
"keys": {
    "p256dh":"BLQELIDm-6b9Bl07YrEuXJ4BL_YBVQ0dvt9NQGGJxIQidJWHPNa9YrouvcQ9d7_MqzvGS9Alz60SZNCG3qfpk=",
    "auth":"4vQK-SvRAN5eo-8ASlrwA=="
    }
}

How does the push service know which client sends the message? The endpoint URL contains a unique identifier. This identifier is used to route the message sent to the correct device and identify which service worker processes the request when the browser processes it.

Identifiers are opaque. As a developer, you can't identify any personal data from it. In addition, it is not stable, so it can not be used to track users.

Because push notifications are paired with service worker s, applications using push notifications must use HTTPS. This ensures that the communication channel between your server and the push service is secure, as well as from the push service to the user.

However, HTTPS cannot ensure that the push service itself is secure. We must ensure that the data sent from your server to the client is not tampered with or directly detected by any third party. You must encrypt the message body on your server.

The following summarizes the process of sending and receiving push messages and displaying push notifications:

Client:

Subscription push service
Send Subscription Objects to Servers

Server side:

Generate the data we want to send to the user
Encryption of data with user public key
The carrier of encrypted data is sent to the endpoint URL.

The message is routed to the user's device. This awakens the browser, which finds the correct service worker and calls the "push" event.

Back to the client:

Receive message data in a push event (if any)
Execute some custom logic in push events
Display notification

Handling push events
The service worker listens for push events and receives messages that are displayed to users through notifications.

serviceworker.js

self.addEventListener('push', function(e) {
  var options = {
    body: 'This notification was generated from a push!',
    icon: 'images/example.png',
    vibrate: [100, 50, 100],
    data: {
      dateOfArrival: Date.now(),
      primaryKey: '2'
    },
    actions: [
      {action: 'explore', title: 'Explore this new world',
        icon: 'images/checkmark.png'},
      {action: 'close', title: 'Close',
        icon: 'images/xmark.png'},
    ]
  };
  e.waitUntil(
    self.registration.showNotification('Hello world!', options)
  );
});

Subscription push notification
Before we send a push message, we must subscribe to the push service.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('sw.js').then(function(reg) {
    console.log('Service Worker Registered!', reg);
    //Get subscription information
    reg.pushManager.getSubscription().then(function(sub) {
      if (sub === null) {
        //Unsubscribed push service. Update page asks user whether to register for push
      } else {
        // We have a subscription, update the database
        console.log('Subscription object: ', sub);
      }
    });
  })
   .catch(function(err) {
    console.log('Service Worker registration failed: ', err);
  });
}

If there is no subscription object, we can update our user interface and ask if the user wants to be notified.
Suppose the user enabled notification. Now we can subscribe to push services.

function subscribeUser() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(function(reg) {

      reg.pushManager.subscribe({
        userVisibleOnly: true//Pass a flag named userVisibleOnly to the subscribe method. By setting it totrue,Browsers can ensure that each incoming message has a matching (visible) notification.
      }).then(function(sub) {
        console.log('Endpoint URL: ', sub.endpoint);
      }).catch(function(e) {
        if (Notification.permission === 'denied') {
          console.warn('Permission for notifications was denied');
        } else {
          console.error('Unable to subscribe to push', e);
        }
      });
    })
  }
}

Web Push Protocol
The Web Push protocol is the formal standard for sending push messages to browsers. It describes how to create the structure and process of push message, encrypt it and send it to Push messaging platform. The protocol abstracts the details of the messaging platform and browser owned by users.

Posted by rileyrichter on Fri, 14 Dec 2018 14:24:03 -0800