我正在尝试使用Firebase Cloud Messaging发送基本通知,但我无法为我的生活弄清楚如何在通知中包含任何实际内容。
我基本上是从这里可以找到的一个精简版本开始的。我有三份文件,一份清单。Json,看起来像这样:
{ "gcm_sender_id": "my sender id" }
一个index.html,看起来像这样:
<html>
<head><link rel="manifest" href="manifest.json"></head>
<body>
<div id="endpoint-show">There doesn't seem to be an endpoint right now</div>
<script src="https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js"></script>
<script>
var config = {apiKey: "my key", authDomain: "my domain", messagingSenderId: "my id"};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function() { console.log('Notification permission granted.'); })
.catch(function(err) { console.log('Unable to get permission to notify. ', err); });
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true})
.then(function(subscription) {
document.getElementById("endpoint-show").innerHTML = "<p>" + subscription.endpoint.split('/').slice(-1)[0] + "</p>";
})
});
navigator.serviceWorker.register('./service-worker.js')
</script>
</body>
<html>
和service-worker.js,如下所示:
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
event.waitUntil(self.registration.showNotification("title", { body: "body" }));
});
这似乎是注册推送通知订阅并建立service worker来处理它们所需的最小代码量。
然后使用curl命令发送通知,如下所示。即,POST到https://fcm.googleapis.com/fcm/send与那些特定的头集和一个主体,其中包含一个"太"字段,这是等于我的idex.html显示。这是有效的,只要我在我的计算机上收到标题为"title"和正文为"body"的通知。
但这就是我卡住的地方:似乎我可以通过此请求发送的唯一数据是通知发生的事实,而不是任何其他(实际)数据。我链接的第一个示例只是硬编码通知,就像我自己的代码一样,但我希望能够发送带有任意数据的请求。这里的文档似乎表明,我应该能够设置请求的data
或notification
字段,并获得具有该数据的通知,但这似乎不起作用。我已经在请求中设置了这两个字段,所以整个事情看起来像这样(我使用postman发送):
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=my key
Cache-Control: no-cache
Postman-Token: some token
{
"notification": {
"body": "notification body",
"title": "notification title"
},
"data": {
"body": "data body",
"title": "data title"
},
"to" : "my endpoint"
}
但我不知道如何实际检索这些数据。我的service worker捕获的事件不包含任何这些数据。我所看过的文档似乎都没有描述如何通过网络实际获取这些数据,仅在Android或iOS上,但显然这是可能的,因为许多网站实现动态通知。
我怀疑我对这一切是如何工作的有一些根本性的误解,这并不奇怪,因为我对任何类型的web开发都没有什么经验。如果我想做的事情是不可能的,或者可以用完全不同的方法来做,请告诉我。
重申一下,这就是我想要做的:
发送请求(无论是我写的web服务器还是firebase)
有一个通知弹出在我的Chrome浏览器从该请求的信息
您似乎将新的firebase消息库与老式的service worker代码混合在一起了。
获得权限后,需要调用getToken API。
// service.js
// after request permission is successful
// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
// Show permission UI.
updateUIForPushPermissionRequired();
setTokenSentToServer(false);
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
showToken('Error retrieving Instance ID token. ', err);
setTokenSentToServer(false);
});
这是有争议的,但你也需要创建一个服务工作,文件名为firebase-messaging-sw.js。参考资料可在此找到。
在这个service worker中,你需要添加这样的内容:
// firebase-messaging-sw.js
'use strict';
console.log('Starting service worker');
if( 'function' === typeof importScripts) {
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js');
importScripts('core/decoder.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': 'YOUR-SENDER-ID'
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
var shinyData = payload || {};
console.log('[firebase-messaging-sw.js] Received background message ', payload, shinyData);
return self.registration.showNotification(shinyData.title, {
body: shinyData.body,
icon: shinyData.icon,
data: {url: shinyData.tag}
})
});
}
你可能会发现我创建的要点很有用。