push.js icon indicating copy to clipboard operation
push.js copied to clipboard

Notification events not working with service workers

Open luke-john opened this issue 9 years ago • 18 comments

Currently on browsers with service workers push.js is not able to handle any events on the notification.

https://github.com/Nickersoft/push.js/blob/93014bc9b52e146426aa9b7c453b03d45549151c/push.js#L189

luke-john avatar Aug 22 '16 02:08 luke-john

Could you please elaborate?

Nickersoft avatar Aug 22 '16 03:08 Nickersoft

Sure,

So when using a browser such as android chrome which does not have support for the Notification API, push.js uses a serviceworker instead.

Currently the logic push.js uses for serviceworker push notifications is to simply register the serviceworker and then call showNotification on it.

This means pretty much all the logic following this is unused

https://github.com/Nickersoft/push.js/blob/93014bc9b52e146426aa9b7c453b03d45549151c/push.js#L245-L284 // notification will be undefined

As a result the following push.js options do not work on android chrome

onClick: Callback to execute when the notification is clicked.
onError: Callback to execute when if the notification throws an error.

I've had a quick look at the service worker documentation and it doesn't look like it's trivial to wire up that logic to the serviceworker notification.

luke-john avatar Aug 22 '16 03:08 luke-john

Oh shucks, you're right. The notification variable is never being assigned. I'll start working on a fix as soon as I can. Shouldn't be too hard.

Nickersoft avatar Aug 22 '16 11:08 Nickersoft

Thanks for the explanation

Nickersoft avatar Aug 22 '16 11:08 Nickersoft

I apologize that I've been sort of MIA for these past few months, but I am currently working on merging in a change that will fix this issue.

Nickersoft avatar Oct 18 '16 17:10 Nickersoft

@Nickersoft Any update on when mobile notifications will start working again?

nickmask avatar Oct 31 '16 21:10 nickmask

@nickmask Mobile notifications never stopped working (unless there is some issue I am not aware of). This issue had to do with notification events not firing and throwing console errors on mobile. While this issue has been fixed in bc8932df0f1d8b5a648b163e16fa4f4e3ad5b49a, it has not been published to NPM yet, as there were some additional changes I was hoping to make before the next release.

Nickersoft avatar Nov 05 '16 18:11 Nickersoft

While this issue has been fixed in bc8932d

Was it? Did you check it? As far as i see, it wasn't (or even it can't be) fixed - there is no such event as "notificationclink" outside of service worker.

The ServiceWorkerGlobalScope.onnotificationclick property is an event handler called whenever the notificationclick event is dispatched on the ServiceWorkerGlobalScope object, that is when a user clicks on a displayed notification spawned by ServiceWorkerRegistration.showNotification().

Notifications created on the main thread or in workers which aren't service workers using the Notification() constructor will instead receive a click event on the Notification object itself.

Reference: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/onnotificationclick

My current solution is to add notificationclick event listener inside the service worker and then pass it to the parent window via postMessage. You can find an example here - https://github.com/dmitry-korolev/push-js

dmitry-korolev avatar Nov 18 '16 14:11 dmitry-korolev

Hello @Nickersoft ,

Same problem here, the notification is shown on mobile but methods (onClick, onShow, ...) don't trigger. Any news about this ?

Thanks !

Oupsla avatar Mar 20 '17 11:03 Oupsla

@Nickersoft What is the status of this issue? How to get onClick to work on Android Chrome browser?

Glennmen avatar Jul 10 '17 22:07 Glennmen

Hi guys. I'm currently looking into an issue where the link option doesn't seem to be operational on the Push homepage. onClick is in the same block of code so it's most likely a related issue. It's weird though... could have sworn link was working. Also, @Oupsla, onClick is the only event that can be triggered on mobile notifications (I thought it said that in the documentation... I might have accidentally removed it). This is just due to how the notifications framework operates. The Notifications API (which mobile notifications don't use) is the only API that supports onShow, onError, etc. Sorry for the snag in the release of v1.0. I'll see if I can get it resolved within a few days.

Nickersoft avatar Jul 11 '17 01:07 Nickersoft

Hello @Nickersoft , Any news about the onClick issue on Android Chrome browser? I recently test Push.js 1.0.5, works fine on desktop but unfortunately, it only display the notification without click action on mobile (Chrome 61). Thanks

Edit: with link: '/#' option, browser show up and load a new page of the website.

anthonyG78 avatar Oct 11 '17 08:10 anthonyG78

HI @Nickersoft please let us know why the onclick is not working on Android chrome?

It is not fixed???

afridi26 avatar Nov 27 '18 16:11 afridi26

To be completely honest, I forget what the outcome of my investigation was :/ I can try to reproduce the issue again soon. Looping in @theLufenk to see if he may be able to assist as well.

Nickersoft avatar Nov 27 '18 17:11 Nickersoft

@Nickersoft I was off the grid for a while. Sorry about that !

AFAIK, @dmitry-korolev is correct. The only possible solution IMO would be adding an Event Listener inside the service worker.

I don't think we want to force the folks to use a compulsory piece of code in their ServiceWorkers. However, since an EventListener for notificationclick is anyhow required for onclick handler to work, we can reflect the same in the Documentation and also add it to the barebones ServiceWorker that has already been provided in the project.

There is another problem though. While Notification.onclick enables us to attach the click handler function to every Notification instance we create, the ServiceWorker logic for the same entails registering a common Event Handler for all notification generated. But, we do have the 'tag' property to make out the different Notification instances from one another.

So in effect, we can have a message event listener inside Push.js that fires when the ServiceWorker send a message with postMessage. This event listener will need to figure out if it's a message relevant to Push.js (can be done by choosing a unique event string such as "PushJSNotificationClickEventMessage"). The "tag" property of the target notification would be a payload for the event. The "tag" can be used to find the notification instance from the notifications={} mapping we keep. This instance now has a onclick property which is the target function that needs to be invoked.

@Nickersoft @dmitry-korolev I would love to have your opinions on this approach and see if it is a possible solution ATM. And also, how we can refine the process in order not to cause a regression on the "Install and use with minimum hassles" aspect of the library.

Let me also try and send in a pull request. Doesn't seem like a lot of changes TBH.

theLufenk avatar Dec 18 '18 09:12 theLufenk

nudge @Nickersoft @dmitry-korolev

theLufenk avatar Jan 10 '19 19:01 theLufenk

Hey @theLufenk @dmitry-korolev, sorry for the delay here – I think this approach sounds reasonable if you wanted to give it a shot.

Nickersoft avatar Feb 26 '19 19:02 Nickersoft

Add this event listner into your service worker For android chrome

self.addEventListener('notificationclick', function(event) { let url = "https://www.google.com"; event.notification.close(); // Android needs explicit close. event.waitUntil( clients.matchAll({type: 'window'}).then( windowClients => { // Check if there is already a window/tab open with the target URL for (var i = 0; i < windowClients.length; i++) { var client = windowClients[i]; // If so, just focus it. if (client.url === url && 'focus' in client) { return client.focus(); } } // If not, then open the target URL in a new window/tab. if (clients.openWindow) { return clients.openWindow(url); } }) ); });

avnishalok avatar Feb 16 '21 15:02 avnishalok