Angular 7 pwa/ SwPush - push notifications not working
You need to install Angular CLI, PWA for service worker, webpush for generating VAPID keys and http-server for running a mock server. You can do it by running:
npm i -g @angular/cli --saveng add @angular/pwa --savenpm i webpush --savenpm i http-server -g --save
Now you need to generate VAPID key pair using webpush for using it in front end and backend
web-push generate-vapid-keys --json
Save the generated pair somewhere. Use the below code in the app.component.ts to request a subscription from the user
import { Component } from '@angular/core';import { SwPush } from '@angular/service-worker';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent { constructor(swPush: SwPush) {if (swPush.isEnabled) { swPush.requestSubscription({ serverPublicKey: VAPID_PUBLIC_KEY }) .then(subscription => { // send subscription to the server }) .catch(console.error);} }}
VAPID_PUBLIC_KEY is the public key you got earlier.
Add this on your Angular project inside the node_modules/@angular/service-worker/ngsw-worker.js
this.scope.addEventListener('notificationclick', (event) => { console.log('[Service Worker] Notification click Received. event:%s', event); event.notification.close(); if (clients.openWindow && event.notification.data.url) { event.waitUntil(clients.openWindow(event.notification.data.url)); } });
You can enter the above code where you find the below line inside the file> it would be in line number 1893.
this.scope.addEventListener('notificationclick', (event) => ..
And you have to build the dist again for this to work.Now use
ng build --prod
to generate the dist and serve it using
http-server ./dist/YOUR_DIST_FOLDER_NAME -p 9999
And in backend file your could should be something like this.
const express = require('express');const webpush = require('web-push');const cors = require('cors');const bodyParser = require('body-parser');const PUBLIC_VAPID = 'PUBLIC_VAPID_KEY';const PRIVATE_VAPID = 'PRIVATE_VAPID_KEY';const fakeDatabase = [];const app = express();app.use(cors());app.use(bodyParser.json());webpush.setVapidDetails('mailto:you@domain.com', PUBLIC_VAPID, PRIVATE_VAPID);app.post('/subscription', (req, res) => { const subscription = req.body; fakeDatabase.push(subscription); });app.post('/sendNotification', (req, res) => { const notificationPayload = { {"notification": { "body":"This is a message.", "title":"PUSH MESSAGE", "vibrate":300,100,400,100,400,100,400], "icon":"ICON_URL", "tag":"push demo", "requireInteraction":true, "renotify":true, "data": { "url":"https://google.com"} } } }; const promises = []; fakeDatabase.forEach(subscription => { promises.push(webpush.sendNotification(subscription, JSON.stringify(notificationPayload))); }); Promise.all(promises).then(() => res.sendStatus(200));});app.listen(3000, () => { console.log('Server started on port 3000');});
Inside the url you can enter your url and on clicking notification your push notification will open the given link and focus it in the browser.
for the service-worker to works you need to compile with --prod.try to compile using ng build --prod
In my case, Google Chrome notifications was disabled on my Windows machine, in Notifications & actions settings.