android - PWA 停止在 android 应用关闭时接收推送通知
问题描述
我创建了一个带有 Service Worker 的简单 PWA 应用程序,它在需要时从我的服务器接收推送通知,并向用户显示通知。当应用程序在前台运行并且应用程序在后台运行几分钟时,这非常有用,推送通知会被接收并按预期显示给用户。但是在后台过了几分钟或者如果应用程序关闭,PWA 将停止接收这些推送通知。
到目前为止我所拥有的:
服务工作者.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
}
据我了解,即使应用程序已关闭,也应在收到推送通知时唤醒 android 上的服务人员。我应该为服务工作者做一个特定的代码,以便在需要时被唤醒?
解决方案
发现了问题。这里的问题是服务工作者上的事件侦听器让客户端验证应用程序是否已经打开,但我假设列表中总会有一个客户端,即使应用程序关闭也是如此。正确的方法是这样的:
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))
}
})
)
})
推荐阅读
- javascript - 当我的异步函数前面没有等待时,try catch 块会捕获错误吗?
- sql - 无法找出转换 sql 附近的错误
- ios - Swift 4 如何从日历中获取所有事件?
- java - 在 ubntu(linux) 中找不到 Firefox 二进制路径
- android - 无法解析行 anko kotlin
- phantomjs - PhantomJS 或 CasperJS 表单自动提交
- spring-boot - 考虑在你的配置中定义一个“reactor.core.scheduler.Scheduler”类型的bean
- python - numpy:沿第三维连接两个数组
- nginx - E: 无法锁定管理目录 (/var/lib/dpkg/),你是 root 吗?树莓派
- ios - SDWebImage 错误的单元格图像