Hi ![]()
We ran into a weird behavior (or probably a bug…) with setting up push notifications in the iOS PWA. The UI acts as if the push notification subscription was set up, while in the background nothing happened yet and the user will never receive any push notification.
(tl;dr I think I know how to fix it and can provide a PR)
Steps to reproduce 
The problem is about enabling push notifications immediately after installing the PWA on iOS.
- Open your Discourse instance in mobile Safari on iOS
- Open up the share menu and choose “Add to home screen”
- Open the new PWA on your home screen
- You see a banner asking you whether you want enable push notification
- Click on the “enable notifications” link
- You see a system dialog
“xyz” would like to send you notifications"- accept it.
- You see a system dialog
- Navigating to your notification preferences, you’ll see
live notificationsnot enabled.- Checking on the server, you also won’t find a new
PushSubscriptionrecord for the user.
- Checking on the server, you also won’t find a new
Expected behavior 
After step 5, you’d already receive a push notification that notifications are enabled. There should also be a new PushSubscription record for your current user in the database and their setting to receive live notifications in the PWA should be enabled.
Problem 
On a freshly launched PWA, the service worker has installed and activated, but does not yet control the page. With that, the check in lib/push-notifications.js, isPushNotificationsSupported(), will still return false, since navigation.serviceworker.controller returns null. These are the important two lines:
navigator.serviceWorker.controller &&
navigator.serviceWorker.controller.state === "activated"
With that, the UI suggests to the user that every is fine with their setup, but they’ll never receive any push notification.
On the first load, the PWA is uncontrolled and the call to subscribe() is never made, even though the user granted permission… ![]()
Users can fix the problem for themselves, if they know how:
- Fully close the PWA (swipe it away…)
- Open the PWA again
- Go to their notification preferences
- Enable
live notificationsagain - -> This time, there should be a new
PushSubscriptionrecord and the notifications are set up.
Potential Fix 
I worked around this problem by registering another service worker that calls skipWaiting() and clients.claim() upon install/activate. Doing so it immediately takes over control over the PWA and the subscription goes through and the respective PushSubscription record is created.
I deployed this as a “hotfix” as part of one of my custom plugins, so that I can fix the situation for my users without diving into a fork of Discourse core…
It’s just two changes:
# plugin.rb
register_service_worker "push-notification-setup.js"
// assets/push-notification-setup.js
self.addEventListener("install", function () {
self.skipWaiting();
});
self.addEventListener("activate", function (event) {
event.waitUntil(self.clients.claim());
});
I think this fix belongs into Discourse core though. With that I’m doing, the plugin is taking over unnecessary control over the PWA. I can provide a PR that adjusts the checks in Discourse core accordingly so that subscribing actually works. I’ll like it here, but feel free to already voice your opinions on the topic.