我正在编写我的第一个 PWA 应用程序。我正在使用 Firebase 来处理我的数据存储和订阅。我有(看起来它创建了一个订阅),但我没有通过浏览器(Chrome 和 Safari)收到任何通知。我已经检查并且 localhost:8080 确实允许通知。
检查 Firebase 日志我能看到的唯一问题是以下日志条目: storePostData body: 'invalid JWT provided\n',
我可以看到帖子被添加到 Firebase 数据库中,因此正在存储数据。
我发现了一个 github 帖子(https://github.com/web-push-libs/web-push/issues/532)说这可能是 VAPID 和生成的问题,这是我用来生成我的公共/私人的包键。</p>
这是我用来创建和订阅的代码。任何指针将不胜感激。
Index.js - 代码作为函数在 Firebase 上运行
exports.storePostData = functions.https.onRequest(function (request, response) {
cors(request, response, function () {
admin.database().ref('posts').push({
id: request.body.id,
title: request.body.title,
location: request.body.location,
image: request.body.image
})
.then(function () {
webpush.setVapidDetails('mailto:bob@icloud.com', 'BPdti0IluU-fmQFrrlZirLF99AuHtJTmvnn8Q_qUW_9SvVy4TQNKBbXcy2LTqgQQImDvNWh-7VNsu2JNj1E2QuY', '<private key>');
return admin.database().ref('subscriptions').once('value');
})
.then(function (subscriptions) {
subscriptions.forEach(function (sub) {
var pushConfig = {
endpoint: sub.val().endpoint,
keys: {
auth: sub.val().keys.auth,
p256dh: sub.val().keys.p256dh
}
};
webpush.sendNotification(pushConfig, JSON.stringify({title: 'New Post', content: 'New Post added!'}))
.catch(function(err) {
console.log(err);
})
});
response.status(201).json({message: 'Data stored', id: request.body.id});
})
.catch(function (err) {
response.status(500).json({error: err});
});
});
});
应用程序.js
function configurePushSub() {
if (!('serviceWorker' in navigator)) {
return;
}
var reg;
navigator.serviceWorker.ready
.then(function(swreg) {
reg = swreg;
return swreg.pushManager.getSubscription();
})
.then(function(sub) {
if (sub === null) {
// Create a new subscription
var vapidPublicKey = 'BPdti0IluU-fmQFrrlZirLF99AuHtJTmvnn8Q_qUW_9SvVy4TQNKBbXcy2LTqgQQImDvNWh-7VNsu2JNj1E2QuY';
var convertedVapidPublicKey = urlBase64ToUint8Array(vapidPublicKey);
return reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedVapidPublicKey
});
} else {
console.log('We have a subscription');
}
})
.then(function(newSub) {
console.log('About to create a new subscription');
return fetch('https://pwagram-ce869-default-rtdb.europe-west1.firebasedatabase.app/subscriptions.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(newSub)
})
})
.then(function(res) {
if (res.ok) {
displayConfirmNotification();
}
})
.catch(function(err) {
console.log(err);
});
}
服务人员
self.addEventListener('push', function(event) {
console.log('Push Notification received', event);
var data = {title: 'New!', content: 'Something new happened!'};
if (event.data) {
data = JSON.parse(event.data.text());
}
var options = {
body: data.content,
icon: '/src/images/icons/app-icon-96x96.png',
badge: '/src/images/icons/app-icon-96x96.png'
};
event.waitUntil(
self.registration.showNotification(data.title, options)
);
});
辅助方法
function urlBase64ToUint8Array(base64String) {
var padding = '='.repeat((4 - base64String.length % 4) % 4);
var base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
var rawData = window.atob(base64);
var outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}