我正试图让Firebase Cloud Messaging在我的网站的移动浏览器上运行,但在检索设备令牌时一直遇到问题,如图所示。我的网站是在Angular中构建的,并通过HTTPS在一个真实的域上提供服务,相关的FCM代码基本上是:
import firebase from 'firebase/app';
import "firebase/messaging";
const app = firebase.initializeApp({...});
const messaging = firebase.messaging(app);
messaging.getToken({vapidKey: '...'})
.then((token) => {
console.log('got token: ', token);
}).catch((err) => {
console.log(err)
});
这在桌面浏览器和移动设备上的Chrome上都能很好地工作,但我还没能用最新的Firefox在Android上的Firefox上工作。它确实正确地请求了通知权限,但由于一个看似空的值,它只是从Firebase库中抛出了一个错误:
TypeError: pushSubscription is null
getToken index.esm.js:632
step tslib.es6.js:102
verb tslib.es6.js:83
fulfilled tslib.es6.js:73
Angular 21
promisifyRequest idb.js:13
ZoneAwarePromise Angular
promisifyRequest idb.js:12
p idb.js:27
ZoneAwarePromise Angular
promisifyRequestCall idb.js:25
deleteDb idb.js:308
migrateOldDatabase index.esm.js:268
step tslib.es6.js:102
verb tslib.es6.js:83
fulfilled tslib.es6.js:73
Angular 21
promisifyRequest idb.js:13
ZoneAwarePromise Angular
promisifyRequest idb.js:12
p idb.js:27
ZoneAwarePromise Angular
promisifyRequestCall idb.js:25
deleteDb idb.js:308
migrateOldDatabase index.esm.js:265
step tslib.es6.js:102
verb tslib.es6.js:83
fulfilled tslib.es6.js:73
Angular 11
Firefox调试将lib代码显示为:
function getToken(firebaseDependencies, swRegistration, vapidKey) {
return Object(tslib__WEBPACK_IMPORTED_MODULE_3__["__awaiter"])(this, void 0, void 0, function () {
var pushSubscription, tokenDetails, subscriptionOptions, e_1;
return Object(tslib__WEBPACK_IMPORTED_MODULE_3__["__generator"])(this, function (_a) {
switch (_a.label) {
case 0:
if (Notification.permission !== 'granted') {
throw ERROR_FACTORY.create("permission-blocked" /* PERMISSION_BLOCKED */);
}
return [4 /*yield*/, getPushSubscription(swRegistration, vapidKey)];
case 1:
pushSubscription = _a.sent();
return [4 /*yield*/, dbGet(firebaseDependencies)];
case 2:
tokenDetails = _a.sent();
subscriptionOptions = {
vapidKey: vapidKey,
swScope: swRegistration.scope,
endpoint: pushSubscription.endpoint, // pushSubscription is null
auth: arrayToBase64(pushSubscription.getKey('auth')),
p256dh: arrayToBase64(pushSubscription.getKey('p256dh'))
};
我可以看到,在桌面上,有一些从lib到Google APIS的网络调用,用于发送安装和注册等信息,以及创建一个在移动设备上不会发生的安装DB。
在尝试了其他订阅方式后,我认为问题实际上是安卓系统上的Firefox没有正确生成订阅。在桌面上调试Firefox主进程我可以看到对updates.push.services.mozilla.com的调用,该调用返回一个410,似乎表明该设备不再有可使用的端点。擦除应用程序的数据(在Android设置中,而不仅仅是清除浏览数据(会迫使它重新生成一个数据,然后它就可以工作了。
这显然是一个已知的问题:https://github.com/mozilla-services/autopush/issues/1445除了对应用程序进行出厂重置外,没有其他解决方案。我只是运气不好,有两台设备都受到了这个bug的影响。