Push Notifications using Angular

  •        0
  

We aggregate and tag open source projects. We have collections of more than one million projects. Check out the projects section.



Notifications is a message pushed to user's device passively. Browser supports notifications and push API that allows to send message asynchronously to the user. Messages are sent with the help of service workers, it runs as background tasks to receive and relay the messages to the desktop if the application is not opened. It uses web push protocol to register the server and send message to the application. Once user opt-in for the updates, it is effective way of re-engaging users with customized content. To know more on the notifications, refer the article introduction to push notifications.

Angular provides a wrapper module for service worker(@angular/service-worker) which will make easy for developers to quickly implement the push notifications to their application.

Push notification on the contrary it destructs the user if he doesn't like it. Browser takes the responsibility of sending the messages only if user accepts the messages and it also maintains its own push service through which push messages can flow to the browser. So application has to send the message to push service and it sends the messages to user if he allows it.

In this article, I will explain how a simple web application subscribes to notifications and receives the notifications. Notifications are created by backend service, which sends messages to the web application. We will also see how we can send recurring notifications or customized message from the backend service.

Two applications will be created, one client application which will receive the message and another notifications backend to send the message to client application. All the communications like creating the subscriptions, sending the messages, pushing the messages happens through web push protocol.

Angular push notification block diagram

We need to create unique Voluntary Application Server Identification (VAPID) keys using which web push protocol communication happens between the push service and client application or push service and notifications backend. To install and generate the web push VAPID keys, please use below command

  yarn global add web-push

web-push generate-vapid-keys --json

It generates vapid keys with public and private key combinations. Public key will be used by the client and public and private key combinations will be stored in notifications backend service.

{
    "publicKey":"BCpUjGH5GSvUeMqI33Xh5xe6BA-awWgTS6B82j6V6GYUsVATgT41qeAJ67fZ1F5srSzt6VXu3cG6slBKpgX_IAA",
    "privateKey":"vOJawCw2OOTUjXjeFiIp5GHPcNXlVzWCXIHd2twPBbs"
}


Apart from that, angular cli, angular pwa, http-server need to be installed. To know more about Angular, refer installing and getting started with Angular and Service worker guide

Create Client Application

Create an angular push notifications project using the below command.

    ng new angular-push-notifications

Then in the app component inject the service worker and check if service worker is enabled. If it is enabled, request for subscription with VAPID server public key to the push service with the help of service worker. If we get the subscription successfully, it need to be passed to notifications backend service through notification service. This subscription details is required for the backend to send the messages.

File: app.component.ts

 import { Component } from '@angular/core';
 import { SwPush } from '@angular/service-worker';
 import { PushNotificationService } from './push-notification.service';

 const VAPID_PUBLIC =
    'BCpUjGH5GSvUeMqI33Xh5xe6BA-awWgTS6B82j6V6GYUsVATgT41qeAJ67fZ1F5srSzt6VXu3cG6slBKpgX_IAA';

 @Component({
     selector: 'app-root',
     templateUrl: './app.component.html',
     styleUrls: ['./app.component.css']
 })

  export class AppComponent {
     title = 'Angular Push Notifications Demo';

  constructor(swpush: SwPush, pushNotificationService: PushNotificationService) {
     if (swpush.isEnabled) {
        swpush.requestSubscription({
           serverPublicKey: VAPID_PUBLIC
       })
    .then((subscription) => {
       console.log(subscription);
       pushNotificationService.sendSubscriptionToTheServer(subscription).subscribe((data)=>console.log(data));
    })
     .catch(console.error);
   }
 }
}

File: push-notification.service.ts

 import { Injectable } from '@angular/core';
 import { HttpClient } from '@angular/common/http';

 const SERVER_URL = 'http://localhost:3000/subscription';

 @Injectable({
    providedIn: 'root'
 })
 export class PushNotificationService {

 constructor(private http: HttpClient) { }

 public sendSubscriptionToTheServer(subscription: PushSubscription) {
       console.log('send subscription');
       return this.http.post(SERVER_URL, subscription);
   }
}


Service worker works in prod environment only in angular application. So we need to build the application with "ng build --prod". Then application can be opened up as below

    http-server -c-1 dist/angular-push-notifications

 

When we open the application, service worker in browser requests for notifications once enabled, it allows to send the message.

 

Notifications Backend Service

Create the node js backend application using the command.

   npm init

Then add the node modules like CORS to enable cross site origin request, body parser to encode and decode the JSON text, web-push for the web push protocol communication and express framework for writing the backend service.

  yarn add body-parser cors express web-push

 

Now web push VAPID details are registered with private and public key. Then subscribe notifications post rest API service is created which will receive the subscription details from the angular application and store it in the temp object.

File: server.js

 const express = require('express');
 const webpush = require('web-push');
 const cors = require('cors');
 const bodyParser = require('body-parser');

 const PUBLIC_VAPID =
         'BCpUjGH5GSvUeMqI33Xh5xe6BA-awWgTS6B82j6V6GYUsVATgT41qeAJ67fZ1F5srSzt6VXu3cG6slBKpgX_IAA';
 const PRIVATE_VAPID =
         'vOJawCw2OOTUjXjeFiIp5GHPcNXlVzWCXIHd2twPBbs';

 const app = express();
 app.use(bodyParser.urlencoded({ extended: false })); 
 app.use(bodyParser.json());

 const fakeDatabase = [];

 app.use(cors());

 webpush.setVapidDetails("mailto:nagappan08@gmail.com", PUBLIC_VAPID, PRIVATE_VAPID);

 app.listen(3000, () => { console.log("server started on port 3000"); });

 app.get('/', (req, res) => {
       res.sendFile('index.html', {root: __dirname });
});

 app.post('/startRecurringNotifications', (req, res) => {
 console.log('setRecurring notifications');
 startNotification();
 res.sendStatus(200);
});

 app.post('/stopRecurringNotifications', (req, res) => {
      console.log('stop recurring notifications');
      clearInterval(intervalObj);
      res.sendStatus(200);
 });


 app.post('/subscription', (req, res) => {
     fakeDatabase.push(req.body);
     console.log(fakeDatabase);
     res.sendStatus(200);

  });

  app.post('/sendNotification', (req, res) => {
     console.log(req.body);
     const notificationPayload = {
       notification: {
           title: req.body.title,
           body: req.body.body,
           icon: 'assets/icons/icon-512*512.png',
   }};
   

   console.log("notificationpayload");
   const promises = [];
   fakeDatabase.forEach(subscription => {
   console.log(JSON.stringify(notificationPayload));
   promises.push(webpush.sendNotification(subscription, JSON.stringify(notificationPayload)));
 });
    Promise.all(promises).then(() => res.sendStatus(200));
 });

  var intervalObj;

  function startNotification() {
        intervalObj = setInterval(function(){
         const notificationPayload = {
         notification: {
            title: 'New Notification',
            body: 'This is notification body',
            icon: 'assets/icons/icon-512*512.png',
   }};

    fakeDatabase.forEach(subscription => {
    console.log("sending notifications");
    console.log(subscription);
    webpush.sendNotification(subscription, JSON.stringify(notificationPayload));
  });
 }, 5000);
}

 

File: index.html

 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>Notifications Backend Portal Page</title>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
 <script>
    $(function() {
        $.ajaxSetup({
            headers: {
              'Content-Type': 'application/json',
              'Accept': 'application/json'
          }
     });

   $('#btn1').on('click', function() {
        console.log("set recurring notifications");

         $.post('/startRecurringNotifications', function(data){
            console.log("successfully set the data");
            console.log(data);
        });
   });

   $('#btn2').on('click', function() {
         console.log("stop recurring notifications");
         $.post('/stopRecurringNotifications', function(data){
              console.log("stop recurring notifications ");
              console.log(data);
         });
    });

    $('#sendMessage').on('click', function() {
         console.log("send message");

        var reqBody = {};
        reqBody.title = $('#msgTitle').val();
        reqBody.body = $('#msgData').val();
        var bodyJson= JSON.stringify(reqBody);

        $.ajax({
           type: "POST",
           dataType: 'application/json',
            url: 'sendNotification',
            data: bodyJson,
         });
   });
});
</script>
</head>
<body>
<div>
<h2>Recurring Notifications for every 10 seconds</h2>
<button id="btn1" style="display: inline-block;">Start Notifications</button>
<button id="btn2" style="display: inline-block;">Stop Notifications</button>
</div>
<div>

<h2>Send customized message to user</h2>
<input type="textbox" id="msgTitle" placeholder="Enter the message title"></input><br/><br/>
<textarea id="msgData" rows="2" cols="50" placeholder="Enter the message data"></textarea>
<button id="sendMessage" style="display:block;">Send</button>
</div>
</body>
</html>


We are going to create two services, one is to send customized message, other for recurring notifications. Create html page to have notification backend service to manage the message sending to different users. Html page will look like below. In the text box we give the message tile and message body to send the message. Backend service is started with following command.

  node server.js

Recurring notifications is like if we start notification, it enables recurring notifications flag so it would be sending the messages in constant time period to the client.

 

Below video will show how the start and stop of recurring notifications works.

   

Nagappan is a techie-geek and a full-stack senior developer having 10+ years of experience in both front-end and back-end. He has experience on front-end web technologies like HTML, CSS, JAVASCRIPT, Angular and expert in Java and related frameworks like Spring, Struts, EJB and RESTEasy framework. He hold bachelors degree in computer science and he is very passionate in learning new technologies.

Subscribe to our newsletter.

We will send mail once in a week about latest updates on open source tools and technologies. subscribe our newsletter



Related Articles

Angular Service Workers Usage Guide

  • angular service-worker offline-app

Web developers come across scenarios like web application completely breaks when workstation goes offline. Likewise to get into our application, every time we need to open a browser and then access it. Instead if it is in app, it will be easy to access for end-user. Push notifications similar to email client need to be done through web application. All these are addressed by a magic called service worker.

Read More


All About Multi-Provider Feature of Angular Version 2.0

  • angular dependency-injection multi-providers

The newly introduced concept of dependency injection in Angular version 2.0 makes it an attractive front-end technology all because of one amazing feature called 'Multi-Providers'. In general, it allows the users to attach certain operations by themselves and a few plugin custom functionality which is not required in our mobile app use case.

Read More


COVID19 Stats using Angular Material Design

  • angular material-design covid covid-stats

Material design is inspired from the real world building architecture language. It is an adaptable system of guidelines, components, and tools that support the best practices of user interface design. Backed by open-source code, Material streamlines collaboration between designers and developers, and helps teams quickly build beautiful products. In this article, we will build COVID stats using Angular Material design.

Read More


Getting Started on Angular 7

  • angular ui-ux front-end-framework

Angular is a platform for building responsive web, native desktop and native mobile applications. Angular client applications are built using HTML, CSS and Typescript. Typescript is a typed superset of Javascript that compiles to plain Javascript. Angular core and optional modules are built using Typescript. Code has been licensed as MIT License.

Read More


Angular Security - Authentication Service

  • angular security authentication jwt

Angular is a framework for creating single page web application. Angular facilitates the security feature and protection mechanism. It provides frameworks by verifying all the routing urls with security authguard interface to validate and verify the user and its permissions.

Read More



JHipster - Generate simple web application code using Spring Boot and Angular

  • jhipster spring-boot angular web-application

JHipster is one of the full-stack web app development platform to generate, develop and deploy. It provides the front end technologies options of React, Angular, Vue mixed with bootstrap and font awesome icons. Last released version is JHipster 6.0.1. It is licensed under Apache 2 license.

Read More


Scene.js - Library to Create Timeline-Based Animation

  • scenejs css timeline javascript animation motion

Scene.js is a JavaScript timeline-based animation library for creating animation websites. As an animated timeline library, it allows you to create a chronological order of movements and positions of objects.

Read More


Univention Corporate Server - An open source identity management system

  • ucs identity-management-system

Univention Corporate Server is an open source identity management system, an IT infrastructure and device management solution and an extensible platform with a store-like App Center that includes tested third party applications and further UCS components: This is what Univention combines in their main product Univention Corporate Server, a Debian GNU/Linux based enterprise distribution. This article provides you the overview of Univention Corporate Server, its feature and installation.

Read More


Build Consulting Website using Next.js

  • react nextjs website-development ssr

One of the popular web framework for building Single page application (SPA) or static site is React library. Application built with React packages will be rendered completely on the client side browser. If you want to reduce the load on client side browser, we need to pre-render the pages in server (Serer side rendering) and serve it to the client. So the client loads the page like simple html page. Also if the pages are rendered from server then search engine will be able to fetch and extract the pages. To do SSR for React, the best abstraction framework is Next.js. In this blog, we will explain how to build a simple consulting website using NextJS.

Read More


React Patent Clause Licensing issue. Is it something to worry?

  • react react-license facebook

React libraries from Facebook is one of the most used UI libraries. It is competitive to AngularJS. There are many open source UI components or frameworks available but mostly people narrow down to two choices Angular / React. Recently Facebook has updated React license and added a patent clause which makes companies to worry and rethink whether to use React or not.

Read More


Generate PDF from Javascript using jsPDF

  • pdf jspdf javascript

We show lot of data in our web applications, it will be awesome if we quickly download specific part of PDF rather than printing it. It will be easy to share for different stakeholders and also for focused meetings. In web application development, download to PDF means, we need to develop backend api specifically and then link it in frontend which takes longer development cylce. Instead it would be really great, if there is way to download what we see in the user interface quickly with few lines of Javascript, similar to export options in word processing application.

Read More







We have large collection of open source products. Follow the tags from Tag Cloud >>


Open source products are scattered around the web. Please provide information about the open source projects you own / you use. Add Projects.