似乎我的PWA创建了多个服务工作者,这在通过FCM接收推送通知时导致不一致的行为。 (我将Push发送到用户的所有fcmTokens,这有效-我在同时打开的多个设备上成功接收到通知)。 例如,我使用PWA打开一个标签并向其发送通知。 Chrome会显示“推送”通知消息,但打开的标签页不会更新。如果我单击通知(以打开托管PWA的相同URL),它将打开一个新标签(现在有2个具有相同URL和相同PWA的标签),只有该标签得到更新/接收推送通知。尽管此选项卡现在可以完全按预期工作,并且是我希望第一次打开PWA时的行为(无需单击通知)。也许这也是一个缓存问题,我运行了两个版本的App,只有其中一个收到更新?
我在智能手机上注意到了相同的行为-新的已部署PWA版本在单击通知之前不会收到更新,有时会发生,有时不会。即使这样做,该应用程序有时也会更新其数据,有时不会。
请帮助我解决问题,并在我的PWA中收到推送通知时保持一致的行为。
我已经尝试在启动PWA之前删除缓存/应用程序数据,但是问题仍然存在。
我的服务人员:
'use strict';
importScripts('./build/sw-toolbox.js');
const version = 0.83;
self.toolbox.options.cache = {
name: 'ionic-cache'
};
// pre-cache our key assets
self.toolbox.precache(
[
'./build/main.js',
'./build/vendor.js',
'./build/main.css',
'./build/polyfills.js',
'index.html',
'manifest.json'
]
);
// dynamically cache any other local assets
self.toolbox.router.any('/*', self.toolbox.fastest);
// for any other requests go to the network, cache,
// and then only use that cached resource if your user goes offline
self.toolbox.router.default = self.toolbox.networkFirst;
importScripts('https://www.gstatic.com/firebasejs/5.5.9/firebase- app.js');
importScripts('https://www.gstatic.com/firebasejs/5.5.9/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': 'XXXX'
});
self.addEventListener('install', function (event) {
// The promise that skipWaiting() returns can be safely ignored.
self.skipWaiting();
// Perform any other actions required for your
// service worker to install, potentially inside
// of event.waitUntil();
});
self.addEventListener("notificationclick", function (event) {
/**event.notification.close();
event.waitUntil(clients.openWindow("/")); **/
const rootUrl = new URL('/', location).href;
event.notification.close();
// Enumerate windows, and call window.focus(), or open a new one.
event.waitUntil(
clients.matchAll().then(matchedClients => {
for (let client of matchedClients) {
if (client.url === rootUrl) {
return client.focus();
}
}
return clients.openWindow("/");
})
);
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
let swPushedessageData = payload.data;
swPushedessageData.job = JSON.parse(payload.data.job);
let notificationTitle;
switch (swPushedessageData.action) {
case 'DELETE':
notificationTitle = 'Auftrag gelöscht';
break;
case 'CREATE':
notificationTitle = 'Neuer Auftrag zugewiesen';
break;
case 'UPDATE':
notificationTitle = 'Auftragsänderung';
break;
}
const notificationOptions = {
icon: '/assets/icon/icon-128x128.png',
actions: [{action: 'open', title: 'Öffnen'}],
};
send_message_to_all_clients(swPushedessageData);
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
function send_message_to_all_clients(msg) {
clients.matchAll().then(clients => {
clients.forEach(client => {
send_message_to_client(client, msg).then(m => console.log("SW Received Message: " + m));
})
})
}
function send_message_to_client(client, msg) {
return new Promise(function (resolve, reject) {
const msg_chan = new MessageChannel();
msg_chan.port1.onmessage = function (event) {
if (event.data.error) {
reject(event.data.error);
} else {
resolve(event.data);
}
};
client.postMessage(msg, [msg_chan.port2]);
});
}
在应用程序中安装Service Worker:
navigator.serviceWorker.register('service-worker.js')
.then((registration) => {
const messaging = this.app.messaging();
this.swIsActive = true;
messaging.useServiceWorker(registration);
this.checkPushMessagingPermissionAfterLogin();
this.swRegistration = registration;
})