我已经设置了一个简单的推送通知网站,如果浏览器位于前台,通知就可以正常运行。
如果浏览器处于后台,问题就开始了:通知到达两次,一个设置了图像和其他设置,另一个只有标题和正文消息。
服务人员的内容:
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': '...'
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ',
return null;
});
self.addEventListener('install', function (event) {
event.waitUntil(skipWaiting());
});
self.addEventListener('activate', function (event) {
event.waitUntil(clients.claim());
});
self.addEventListener('push', function (event) {
var pushData = event.data.json();
try {
var notificationData = pushData.data;
notificationData.data = JSON.parse(notificationData.data);
console.log(notificationData);
self.registration.showNotification(pushData.notification.title, notificationData);
}
catch (err) {
console.log('Push error happened: ', err);
}
});
客户端js:
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.onMessage(function (payload) {
console.log("notification recieved");
return null;
});
self.addEventListener('push', function (event) {
console.log("window push stuff");
return null;
});
谢谢!
答案 0 :(得分:3)
将此行添加到messaging.setBackgroundMessageHandler
事件可以解决此问题:
self.registration.hideNotification();
这样,默认通知就不会显示,您必须在self.addEventListener
事件中显示通知。
答案 1 :(得分:1)
100%避免多次通知的最简单方法是添加"标记",例如:
var options = {
body: "text",
tag: "notification-1"
};
self.registration.showNotification("title", options)
答案 2 :(得分:0)
这就是我如何让 Firebase 云消息通知在具有这些要求的 Android 设备上的 Progresse Web Apps 中工作:
firebase-messaging.sw.js
不要向该文件添加任何 cdoe 或 onBackgroundMessage()
处理程序。我的文件不过是
//Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here. Other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/8.3.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.3.0/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
databaseURL: 'https://project-id.firebaseio.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
if (firebase.messaging.isSupported()) {
const messaging = !firebase.apps.length
? firebase.initializeApp(firebaseConfig).messaging()
: firebase.app().messaging();
发送通知的服务器端作业
消息有效载荷的内容和结构是关键。将您的通知对象放入 webpush 对象中。请勿添加数据对象,以避免内容不完整的重复通知。
确保您的徽章是 24x24px png,在透明背景上仅包含白色内容。
var message = {
webpush: {
notification: {
title: "Let's Join App", // Your message title
body: messageBody, // Your message body
icon: "./img/icons/android-chrome-192x192.png", // Your App icon, up to 512x512px, any color
badge: "./img/icons/badge.png", // Your app badge, 24x24px, white content on transparent background
},
fcmOptions: {
link: "https://www.letsjoin.app", // Your Link
},
},
token,
};
// Send a message to the device corresponding to the provided
// registration token.
await admin
.messaging()
.send(message)
.then((response) => {
// Response is a message ID string.
console.log("Successfully sent message");
})
.catch((error) => {
console.log("Error sending message:", error.errorInfo.message);
});
};
答案 3 :(得分:0)
我花了大约两周的时间才理解并解决了这个问题。希望这会为其他人节省时间:
Firebase 支持两种类型的推送通知:
Firebase 云消息传递界面具有许多优势,例如按国家/地区、设备、语言等进行高级定位。但它只允许在数据自定义字段内发送 URL。
从 Firebase 控制台用户界面发送的消息如下所示:
{
notification: {
title: "New Test",
body: "This is test",
},
data: {
url: 'someurl.com',
},
};
通知在 Service Worker 处理时出现两次,在 FCM SDK 自动处理时出现第二次。
我没有找到禁用通知自动处理的方法,并且在前端使用 Firebase 函数仅将其作为数据消息发送:
{
data: {
title: "New Test",
body: "This is test",
url: 'someurl.com',
},
};
因此,如果您想将自定义 URL 传递给推送通知,则需要从您自己的服务器或使用 firebase 函数发送它。