Open PWA when clicking on push notification handled by service-worker ng7 + android Open PWA when clicking on push notification handled by service-worker ng7 + android angular angular

Open PWA when clicking on push notification handled by service-worker ng7 + android


Though the provided solutions work, it will be nice to have an approach which does not modify service worker code in node_modules or the generated code.

The approach can be to create another script named custom-service-worker.js

In this file,

importScripts('./ngsw-worker.js');(function () {    'use strict';    self.addEventListener('notificationclick', (event) => {        console.log("This is custom service worker notificationclick method.");        console.log('Notification details: ', event.notification);        // Write the code to open        if (clients.openWindow && event.notification.data.url) {            event.waitUntil(clients.openWindow(event.notification.data.url));        }    });}());

Register custom-service-worker.js as the service worker in place of ngsw-worker.js in the imports section where ServiceWorkerModule.register would be written.

Also don't forget to add this script as asset in angular.json so that it gets copied in the dist folder.

I believe this approach saves us the hassle of doing anything extra to edit the original service worker file.


Unfortunately you won't be able to open your PWA from angular code. The SwPush interface will work nicely if the app is currently open.

If your application is closed, the only thing running will be your service worker (provided it was registered succesfully). So the solution to your problem is editing angular's service worker file.

In angular 7 (specifically referring to "@angular/service-worker" v~7.2.0), after you build your app with ng build --prod, examine your /dist folder and look for the file ngsw-worker.js. Open it in an editor.

On line 1885, you will find:

this.scope.addEventListener('notificationclick', (event) => this.onClick(event));

Change it to:

this.scope.addEventListener('notificationclick', (event) => {    event.notification.close();    if (clients.openWindow && event.notification.data.url) {        event.waitUntil(clients.openWindow(event.notification.data.url));    }});

This implies that you passed in the notification payload a data object with the desired URL. e.g:

{     title: "Hello",     body: "Here, open this URL",    data: {         url : "/somewhere/over/the/rainbow/42"    } }

Things to have in mind:

  • If you have any automated build pipelines (CD), you'll have to change your ngsw-worker.js manually (but you could manage to deploy your service worker file after ng build --prod process completes) ;
  • Everytime you build to prod, ngsw-worker.js will be overwritten. @Jay's answer below offer a better approach to avoid this problem.
  • I know you are developing on android, but if you're having trouble seeing changes, you could use Chrome Dev tools to [A] force update the service worker or [B] to open the current ngsw-worker.js file and verify if it's the desired version. The solution works for installed apps on your desktop as well.

enter image description here

Related links:

How can I initiate a PWA (progressive webapp) open from a click on a push notification?

https://github.com/angular/angular/issues/20956


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 can find this line inside the file

this.scope.addEventListener('notificationclick', (event) => ..

And you have to build the dist again for this to work. And in backend you would need to use this format:

{"notification":{"body":"This is a message.","title":"PUSH MESSAGE","vibrate":[300,100,400,100,400,100,400],"icon":"https://upload.wikimedia.org/wikipedia/en/thumb/3/34/AlthepalHappyface.svg/256px-AlthepalHappyface.svg.png","tag":"push demo","requireInteraction":true,"renotify":true,"data":{"url":"https://maps.google.com"}}}

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. YOu dont need to change anything inside the dist.