首页 > 解决方案 > PushManager 订阅在 Firefox for Android 上失败

问题描述

我正在努力在我的网络应用程序中集成网络推送通知。一切都适用于桌面版 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方法不会引发错误。而是运行回调,但带有参数nullsubscription。因此,该过程仍然失败。

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!");

确实有效,原则上证明权限不是问题。

标签: javascriptfirefoxpush-notificationservice-workerfirefox-android

解决方案


更新:FF Fenix 团队在显示通知时确认了一个错误

随时在这里跟踪它

对服务人员对 Firefox 移动浏览器的支持感到好奇。努力寻找 Mobile Firefox 的调试工具作为插件或 3rd 方工具,但没有成功。

但是,我已经在 Mobile Firefox 上测试了我的网络推送应用程序,并且可能完全确认Service Worker Registration state存在问题。

为了丢弃我的代码中的任何问题,我使用了Matt Gaunt 的 Webpush Book

我可以告诉马特的服务人员返回注册就像这样简单:

 async function registerSW() {
  await navigator.serviceWorker.register('/demos/notification-examples/service-worker.js');
}

function getSW() {
  return navigator.serviceWorker.getRegistration('/demos/notification-examples/service-worker.js');
}

Firefox for Android 成功请求通知权限,但在您启动 .showNotification 函数时它不会显示推送

这是 Matt 网站的 Badge 示例中的 showNotification 方法示例:

 async function onBadgeClick() {
            const reg = await getSW();
            /**** START badgeNotification ****/
            const title = 'Badge Notification';
            const options = {
                badge: '/demos/notification-examples/images/badge-128x128.png'
            };
            reg.showNotification(title, options);
            /**** END badgeNotification ****/
        }

看起来不错,应该可以正常工作,但对于 Firefox Mobile,它根本不起作用。我想这个问题应该升级到Mozilla。

更新 在 Github 上创建了新的错误报告:


推荐阅读