Reputation: 163
I created a simple PWA application with a Service Worker that is receiving push notifications from my server when needed and show a notification for the user. This works great when the application is running on the foreground and when the application is on background for a few minutes, the push notification is received and shown to the user as intended. But passed a few minutes on background or if the app is closed, the PWA stop receiving these push notifications.
What I have so far:
service-worker.js
self.addEventListener('push', (e) => {
let notificationData
e.waitUntil(
clients.matchAll({ type: 'window' }).then(function(clientList) {
const client = clientList && clientList[0]
if (e.data && client && client.visibilityState !== 'visible') {
const envelope = e.data.json()
// Process the notification
// ...
e.waitUntil(self.registration.showNotification(data.subject, options))
}
})
)
})
index.js
async registerPushNotificationToWorker() {
if ('serviceWorker' in navigator) {
try {
const swRegistration = await navigator.serviceWorker.getRegistration()
let subscription = await swRegistration.pushManager.getSubscription()
let subscriptionJson
if (subscription === null) {
subscriptionJson = await subscribeUser()
} else {
subscriptionJson = subscription.toJSON()
}
// Save subscriptionJson on server
// ...
} catch (e) {
console.log('Service Worker registration failed: ', e)
}
}
}
async subscribeUser() {
if ('serviceWorker' in navigator) {
const swRegistration = await navigator.serviceWorker.ready
try {
const pushSubscription = await swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey
})
return pushSubscription.toJSON()
} catch (e) {
console.log('Error', e)
if (Notification.permission === 'denied') {
console.warn('Permission for notifications was denied')
} else {
console.error('Unable to subscribe to push', e)
}
}
}
return null
}
From what I understood, the service worker on android should be woken up when a push notification is received even if the app is closed. There is a specific code I should do for the service worker to be woken up when needed?
Upvotes: 7
Views: 2738
Reputation: 163
Found the problem. The problem here was the Event Listener on the service-worker was getting the clients to verify if the application was already open, but I was assuming there would always be a client on the list, even when the app is closed. The correct way would be something like:
self.addEventListener('push', (e) => {
let notificationData
e.waitUntil(
clients.matchAll({ type: 'window' }).then(function(clientList) {
const client = clientList.find(c => c.visibilityState === 'visible') // <- This validation
if (e.data && !client) {
const envelope = e.data.json()
// Process the notification
// ...
e.waitUntil(self.registration.showNotification(data.subject, options))
}
})
)
})
Upvotes: 6