我正在尝试实现一个切换开关,以使用 Firebase 消息传递在网络应用中打开/关闭通知。我的通知工作正常,但当用户尝试关闭通知时出现问题。如果我只是通过以下方式取消注册服务工作者:
navigator.serviceWorker.getRegistrations().then((r) => {
return Promise.all(r.map(reg => reg.unregister()));
});
然后,该工作人员确实被取消注册,但如果用户尝试重新打开通知,Firebase 将抛出此错误:
messaging/no-sw-in-reg
该错误是有道理的,但似乎没有任何内置方法可以为不再需要Firebase的用户注销Firebase。您是否应该删除 Firebase 应用,并在用户再次请求通知时重新初始化它?
我意识到我可以删除 firebase 令牌并忘记数据库中的用户,但我不想留下一个永远不会再次调用的无用服务工作者。
让用户在您的网络应用中完全停用 Firebase 通知的正确方法是什么?
我遇到了完全相同的问题。因此,我使用您的代码来摆脱服务工作线程,然后重新启动消息传递对象,因此您可以取消订阅并再次安装服务工作线程,而无需重新加载页面。
我发现会出现此问题(至少在我的代码中(,因为消息传递对象缓存设备令牌,因此它不会触发在获取设备令牌时应触发的事件。因此,当您不想重新加载页面时,重新启动消息传递对象是一个可行的选择。清理消息传递对象缓存将是一个更好的解决方案。
示例代码:
navigator.serviceWorker.getRegistrations().then((r) => {
return Promise.all(r.map(reg => reg.unregister()));
});
this.messaging = firebase.messaging();
愿源头与你同在。
其他人有用,则只能取消订阅推送通知,而不是停用整个 ServiceWorker 。
通过仅取消订阅推送订阅,还可以避免重新分配消息传递属性的需要。
这就是我取消订阅的方式:
/*
Returns a Promise that resolves on the PushSubscription object that controls the push notification subscription, after it finds the coresponding ServiceWorker
*/
getSubscription() : Promise<any>{
if(!navigator) return;
const subscriptions = navigator.serviceWorker.getRegistrations().then((r) => {
return r.map((sw) =>{
if(!(sw.active && sw.active.scriptURL.includes("firebase-messaging")))
return Promise.resolve();
return sw.pushManager.getSubscription();
});
});
return subscriptions.then(arr => arr ? arr[0] : Promise.resolve(null));
}
====
====================================================================================// Unsubscribes PushNotifications
rejectPermission() : Promise<boolean>{
return this.getSubscription().then((pushSubscription : PushSubscription) =>{
return pushSubscription.unsubscribe();
});
}
这就是我为我的应用程序所做的,一切似乎都很好。