@gauchofunky 的回答是正确的。在 Chromium dev slack 频道和 @gauchofunky 上的一些指导下,我能够拼凑出一些东西。以下是解决当前限制的方法;希望我的答案很快就会过时!
首先弄清楚您将如何在后端保留通知。我在 Mongoose 中使用 Node/Express 和 MongoDB,我的架构如下所示:
var NotificationSchema = new Schema({
_user: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
subscriptionId: String,
title: String,
body: String,
sent: { type: Boolean, default: false }
});
如果您想更改图标,请务必添加图标。我每次都使用相同的图标,所以我的在服务人员中是硬编码的。
找出正确的 REST Web 服务需要一些思考。 GET 似乎是一个简单的选择,但获取通知的调用会导致副作用,因此 GET 不可用。我最终选择了POST 到/api/notifications,正文为{subscriptionId: <SUBSCRIPTION_ID>}。在该方法中,我们基本上执行了一个出队:
var subscriptionId = req.body.subscriptionId;
Notification
.findOne({_user: req.user, subscriptionId: subscriptionId, sent: false})
.exec(function(err, notification) {
if(err) { return handleError(res, err); }
notification.sent = true;
notification.save(function(err) {
if(err) { return handleError(res, err); }
return res.status(201).json(notification);
});
});
在 Service Worker 中,我们需要确保在创建 fetch 之前获得订阅。
self.addEventListener('push', function(event) {
event.waitUntil(
self.registration.pushManager.getSubscription().then(function(subscription) {
fetch('/api/notifications/', {
method: 'post',
headers: {
'Authorization': 'Bearer ' + self.token,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
})
.then(function(response) { return response.json(); })
.then(function(data) {
self.registration.showNotification(data.title, {
body: data.body,
icon: 'favicon-196x196.png'
});
})
.catch(function(err) {
console.log('err');
console.log(err);
});
})
);
});
还值得注意的是,订阅对象从 Chrome 43 更改为 Chrome 45。在 Chrome 45 中,subscriptionId 属性已被删除,这只是需要注意的地方 - 此代码是为与 Chrome 43 一起使用而编写的。
我想对我的后端进行经过身份验证的调用,因此我需要弄清楚如何将 JWT 从我的 Angular 应用程序获取到我的服务工作者。我最终使用了postMessage。以下是我注册 service worker 后的操作:
navigator.serviceWorker.register('/service-worker.js', {scope:'./'}).then(function(reg) {
var messenger = reg.installing || navigator.serviceWorker.controller;
messenger.postMessage({token: $localStorage.token});
}).catch(function(err) {
console.log('err');
console.log(err);
});
在 service worker 中监听消息:
self.onmessage.addEventListener('message', function(event) {
self.token = event.data.token;
});
奇怪的是,该监听器在 Chrome 43 中工作,但在 Chrome 45 中不工作。Chrome 45 与这样的处理程序一起工作:
self.addEventListener('message', function(event) {
self.token = event.data.token;
});
现在推送通知需要做很多工作才能让一些有用的东西运行起来——我真的很期待有效载荷!