I am working on adding reminder notifications for my progressive web app, written originally as a Nextjs site. The criteria I have are as follows:
- Functions when device is offline
- Notifications accurate within seconds
- Works when app is backgrounded
- Supports delays from several minutes up to several hours
My initial implementation focused around utilizing a service worker with a handler off of the message
event. The event.waitUntil
is used to extend out the life of the service worker for notifications via adding a Promise.delay
from Bluebird.
This approach works up until the service worker is killed off at around the 5 minute mark of the app being backgrounded. I'm far from the first to have hit up against this limitation, so I've dove into and tried a number of work-arounds.
This question's accepted answer lists a few options in development in 2019:
Periodic Background Sync API
While an app has network connectivity, an app can schedule periodic events on a minimum interval. (reference)
Finding: The chrome implementation relies on a site's engagement score for determining the rate at which syncs can occur. This, the lack of offline support, and lack of browser support in both Firefox and Safari makes it currently a bit of a dead end for my use case.
Notification Triggers
Notifications can have a trigger set on them for when they should show up. One of these being a specific time (issue).
Finding: This is spot on for what I want, but the issue tracking it has been in an open state since 2018.
Scheduled Task API
Allows for running arbitrary tasks without a connectivity requirement (issue).
Finding: This also has been bumped back in priority to limbo.
Alternatives to relying solely on a service worker are described here.
Dedicated Worker Relay
Hold on to calls to the service worker in a dedicated worker, passing them along when close to the time they should show up.
Finding: This works in desktop browsers. Unfortunately, dedicated workers seem to have the same lifespan limitation in mobile as service workers once the app is backgrounded. So, not a functional solution.
Shared Worker Relay
Same as Dedicated Worker Relay, but with a Shared Worker.
Finding: Unfortunately, shared worker support is not available on mobile. So I have not been able to test this solution.
Remaining workarounds:
- Add a native wrapper or variant that needs to deploy through the app store
- no longer a progressive web app + needs a store deploy
- Push notifications
- requires service is aware of and managing client timers (currently doesn't care about client data)
- no longer offline
Still looking for ways to get the offline notifications functioning. I've investigated if keeping a notification open will keep the service worker alive (like native apps do) as well as if there are any special permissions that extend service worker lifespans, but no progress as of yet on those fronts.
Has anyone successfully gotten this sort of behavior functioning?