Angular PWA Badging API:如何实现后台/杀死状态下角标自动更新?
解决PWA后台/被杀状态下推送更新角标问题
问题分析
当前代码仅在应用前台时,通过页面给Service Worker发消息更新角标,但后台或应用被杀时页面未运行,无法触发消息发送,导致角标不更新。核心问题是依赖页面触发角标更新,未利用Service Worker的推送事件唤醒机制。
解决方案
直接在Service Worker的push事件监听器中处理角标更新:
- 修正Service Worker中Badging API的调用方式(SW环境需用
self.registration.setAppBadge而非navigator.setAppBadge) - 监听推送事件,收到推送时直接更新角标(浏览器会自动唤醒SW执行代码,即使应用被杀)
- 统一角标更新逻辑,同时兼容前台页面触发的场景
修改后的代码
fb-sw.js(Service Worker)
// 处理前台页面发来的角标更新消息 self.addEventListener("message", (event) => { if (event.data && event.data.action === "badgeCount") { updateBadge(event.data.count); } }); // 处理推送通知事件(后台/被杀状态下触发) self.addEventListener("push", (event) => { const payload = event.data?.json() || {}; // 从推送 payload 中获取未读计数,或自行维护(如从IndexedDB读取累计值) const unreadCount = payload.unreadCount || 1; // 显示推送通知(iOS必须调用此方法才会唤醒SW处理角标) const notificationOptions = { body: payload.body || "您有新通知", icon: "/icons/icon-192x192.png" // 替换为你的图标路径 }; // 并行执行通知显示和角标更新 event.waitUntil( Promise.all([ self.registration.showNotification(payload.title || "新通知", notificationOptions), updateBadge(unreadCount) ]) ); }); // 统一角标更新工具函数 function updateBadge(count) { if ("setAppBadge" in self.registration) { count > 0 ? self.registration.setAppBadge(count) : self.registration.clearAppBadge(); } else { console.log("Badging API 不受当前浏览器支持"); } }
messaging.ts(前端页面)
return new Promise((resolve, reject) => { if ("setAppBadge" in navigator) { // 前台直接更新角标,无需通过SW转发 navigator.setAppBadge(unreadCount); // 可选:同步角标计数到SW(用于后台累计) navigator.serviceWorker.ready .then(registration => { registration.active?.postMessage({ action: "badgeCount", count: unreadCount }); resolve(unreadCount); }) .catch(err => { console.error("同步角标到SW失败:", err); reject(err); }); } else if ("serviceWorker" in navigator) { // 兼容不支持页面Badging API的浏览器,通过SW更新 navigator.serviceWorker.ready .then(registration => { registration.active?.postMessage({ action: "badgeCount", count: unreadCount }); resolve(unreadCount); }) .catch(err => { console.error("Service Worker 操作失败:", err); reject(err); }); } else { reject(new Error("当前浏览器不支持Service Worker")); } });
关键注意事项
- Service Worker唤醒:推送事件触发时,浏览器会临时唤醒SW执行代码,无需应用处于运行状态,这是后台/被杀状态更新角标的核心。
- iOS特殊要求:
- PWA必须添加到主屏幕
- 用户已授权推送通知权限
- SW的
push事件必须调用showNotification,否则iOS不会唤醒SW处理后续逻辑 - Badging API需iOS 16.4及以上版本支持
- 计数维护:若需累计未读数量,建议将计数存储在IndexedDB中,每次推送时读取、更新并同步到角标,前台页面加载时也从IndexedDB读取最新计数。
内容的提问来源于stack exchange,提问作者Nouman Shah
相关产品推荐
相关产品推荐

