我正在努力在我的网络应用程序中集成网络推送通知。一切都适用于桌面版 Chrome 和 Firefox 以及 Android 版 Chrome,但不适用于Firefox for Android。这个问题似乎讨论了同样的问题,但没有任何回应。
我使用本教程作为 service worker 注册脚本的基础。我添加了一些更多的打印/检查,但大部分是相同的。
因此,当registerServiceWorker
从 FF Android 上的按钮按下调用该方法时,serviceWorker
安装了该方法,该subscribeUser
函数被调用,但该pushManager.subscribe
方法将失败并显示以下错误消息:
DOMException: User denied permission to use the Push API.
这是不正确的,即使在错误打印行上暂停时Notification.permission
也会返回"granted"
。
在每晚构建中执行相同的操作会导致略有不同,但仍然是不正确的行为。该pushManager.subscribe
方法不会引发错误。而是运行回调,但带有参数null
值subscription
。因此,该过程仍然失败。
Service Worker 注册脚本:
'use strict';
function updateSubscriptionOnServer(subscription, apiEndpoint) {
return fetch(apiEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
subscription_json: JSON.stringify(subscription)
})
});
}
function subscribeUser(swRegistration, applicationServerPublicKey, apiEndpoint) {
// It seems browsers can take the base64 string directly.
// const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
console.log(`Subscribing pushManager with appkey ${applicationServerPublicKey}`);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerPublicKey
})
.then(function(subscription) {
console.log('User is subscribed.');
console.log(`Sending subscription data to server (${apiEndpoint})`, subscription);
return updateSubscriptionOnServer(subscription, apiEndpoint);
})
.then(function(response) {
if (!response.ok) {
throw new Error('Bad status code from server.');
}
return response.json();
})
.then(function(responseData) {
console.log(responseData);
if (responseData.status!=="success") {
throw new Error('Bad response from server.');
}
})
.catch(function(err) {
// FF Android says "User denied permission to use the Push API."
console.log('Failed to subscribe the user: ', err);
console.log(err.stack);
});
}
function registerServiceWorker(serviceWorkerUrl, applicationServerPublicKey, apiEndpoint){
let swRegistration = null;
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
console.log(`Current Notification.permission = ${Notification.permission}`);
swRegistration = navigator.serviceWorker.register(serviceWorkerUrl)
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
console.log(`Current Notification.permission = ${Notification.permission}`); // Will give "granted"
subscribeUser(swReg, applicationServerPublicKey, apiEndpoint);
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
return false;
}
return swRegistration;
}
我无法弄清楚如何获得有效的推送订阅。如前所述,我尝试过的所有其他浏览器都可以正常工作。我希望有人能指出我正确的方向。这是 Firefox Android 或我的代码中的错误吗?
使用手动显示通知
new Notification("Hi there!");
确实有效,原则上证明权限不是问题。