我有一个小型的网络应用程序,它接收FCM消息,有一个服务工作者,处理背景消息,一切都很好。服务工作者将收到消息并将其发布回主页面,以便它们显示在页面上。这是为了背景信息。
我的问题是前台消息由一些默认的onMessage()处理,它们将它们作为封装在大消息中的消息传递给主页面。所以,让我们说,如果我在.js或主页本身中定义了我自己的onMessage()函数,则会调用此消息,然后调用默认消息,这会导致消息处理两次。
以下是我收到的信息:
服务工作者的代码是:
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
var config = {
apiKey: "AIzaSyBoi6gB1BHKxFBt58JJ4phWiZr9BKJaphI",
authDomain: "webmessaging-7bef1.firebaseapp.com",
databaseURL: "https://webmessaging-7bef1.firebaseio.com",
projectId: "webmessaging-7bef1",
storageBucket: "webmessaging-7bef1.appspot.com",
messagingSenderId: "649072625962"
};
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': '649072625962'
});
const messaging = firebase.messaging();
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event.notification.tag);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
includeUncontrolled: true,
type: "all"
})
.then(function (clientList) {
console.log('Clients Count: ', clientList.length);
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
var clientUrl = client.url;
console.log('Client URL:', client.url);
if ((clientUrl.indexOf("localhost") != -1) && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('https://deanhume.github.io/typography');
}
})
);
});
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body,
icon: '/fcm-logo.png'
};
clients.matchAll({
includeUncontrolled: true,
type: "all"
})
.then(function (clientList) {
console.log('Clients Count: ', clientList.length);
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
var clientUrl = client.url;
console.log('Client URL:', client.url);
if ((clientUrl.indexOf("localhost") != -1) && 'focus' in client) {
// client.postMessage(payload.data);
}
}
})
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
如果我删除了我的onMessage()处理程序,我仍然会得到默认的onMessage()处理程序发布的消息。
请建议。
...谢谢
[UPDATE] 经过一些彻底的检查,我得出一些结论,问题似乎在于我有以下两个函数,它们通过接收发送到页面的消息看起来完全一样。
当页面在前台并具有焦点时,应该接收消息。
messaging.onMessage(function (payload) {
console.log('Message received: ', payload);
alert(payload.data.title);
// Get the data passed by the message and display on the page...
document.getElementById('Select1').innerHTML += "<option>" + payload.data.title + "</option>";
});
这个意思是接收服务工作者在页面处于后台并且没有焦点时收到消息时传递的数据。
// Listen to messages from service workers.
navigator.serviceWorker.addEventListener('message', function (event) {
console.log("Got reply from service worker: ", event);
// Get the data passed by the message and display on the page...
document.getElementById('Select1').innerHTML += "<option>" + event.data.title + "</option>";
});
所以,基本上,我通过两个处理程序在同一个地方同时收听消息,这导致消息同时被处理两次...... 有什么建议我如何正确组织这段代码?
答案 0 :(得分:1)
几点说明:
1-您不应在服务工作者中包含配置详细信息(因为它位于客户端的末尾)并将其限制为所需的:
firebase.initializeApp({
'messagingSenderId': '649072625962'
});
2- messaging.setBackgroundMessageHandler仅在后台的情况下触发。
3- messaging.onMessage()您没有在服务工作者中定义,而是在您提到的.js中定义处理前景场景的情况,并且将仅触发 在这种情况下(除非你定义它,否则没有默认定义)