我已经尝试了很长时间,将“推送通知”发送到Angular PWA,到目前为止,它还没有起作用。当我从Firebase控制台发送通知时,它按预期工作。没有错误报告,很坦率地说,我不确定是什么错误。简要介绍一下后端:
后端有6个服务。他们都使用Cloud Messaging进行通信。在这种情况下,感兴趣的服务是作业服务和通知服务。通过Job Service API添加作业后,它将在主题jobCreated
上发布一条消息。目前,该主题只有一个订阅:jobCreatedSubscription
。订阅被配置为基于推送的订阅,它指向通知服务中的端点。然后,通知服务需要从Firestore集合中查找设备令牌并发送推送通知。
到目前为止,这是我的代码:
index.js
const admin = require('firebase-admin');
const serviceAccount = require('./path-to-service-account.json');
const ref = admin.initializeApp({
databaseURL: 'https://<APPNAME>.firebaseio.com/',
credential: admin.credential.cert(serviceAccount),
storageBucket: "<BUCKET>.appspot.com"
});
const fcm = require('./common/fcm')({ admin: ref });
为简洁起见,我仅包含代码的相关部分。 fcm
模块导出具有两个功能的对象:sendToOne
和sendToMany
用于将消息发送到一个或多个设备。设置方法如下:
fcm.js
module.exports = function({ admin }) {
const service = admin.messaging();
const messageOpts = {
contentAvailable: true, // for ios wake up
timeToLive: 3600 * 3, // 3 hours
};
return {
sendToOne: async (token, payload) => {
try {
return service.sendToDevice(token, {
data: {
"job": JSON.stringify(payload)
}
}, messageOpts);
} catch(PushSendError) {
console.log('[x] Error while sending Push Notification');
console.error(PushSendError);
}
},
sendToMany: async (tokens, payload) => {
try {
return service.sendMulticast({
notification: {
title: 'New Job',
body: 'Job Notification'
},
tokens,
data: {
job: JSON.stringify(payload)
}
}).then((response) => {
if (response.failureCount > 0) {
response.responses.forEach((resp, idx) => {
console.log(resp);
});
}
else {
console.log('No failures');
console.log(response);
}
return ;
}).catch(e => console.error(e));
} catch(PushSendError) {
console.log('[x] Error while send Push Notification');
console.error(PushSendError);
}
}
};
};
通知服务使用此模块将消息发送到PWA。以下是通知服务的相关代码:
通知服务
const tokens = [];
snap.forEach(doc => {
const d = doc.data();
tokens.push(d.device_token);
});
const payload = {
// all Payload properties are here
};
console.log(tokens);
// await fcm.sendToMany(tokens, payload);
for(const token of tokens) {
// eslint-disable-next-line
await fcm.sendToOne(token, payload);
}
从Firestore检索令牌,控制台按预期方式打印一个令牌(集合中当前有一个设备ID)。 snap
是Firestore查询中的QuerySnapshot。我在代码中添加了适当的日志和错误处理。从日志中,我可以看到打印了令牌,按预期方式打印了有效内容主体(它是通过Cloud Messaging从Job服务发送的)。没有错误。 Cloud PubSub还显示消息为acked
,因为它不会反复不断推送消息。但是,推送通知没有到达PWA。我尝试了很多次都没有成功。
更新1
我将fcm中的方法从sendToDevice
更改为send
并且有效;这有点令人困惑,因为两者都是Firebase中已记录的方法。这是更改的部分:
sendToOne: async (token, payload) => {
try {
return service.send({
data: {
"job": JSON.stringify(payload)
},
token: token
});
} catch(PushSendError) {
console.log('[x] Error while sending Push Notification');
console.error(PushSendError);
}
}
更新2
好的,我们昨天进行了一些测试。我们面临与推送通知传递相关的一些未知问题。在10次中,我们最多只能收到3-4次通知。其余的通知永远不会到达。我已记录来自send
的响应,它返回一个消息ID,并且没有其他错误。用于服务间通信的基于主题的消息传递正在顺利进行,没有遗漏。但是,Web推送确实存在问题,无法正常工作。缺乏调试支持使我们无法进一步了解问题所在。由于消息不时到达,所以就我们所知,这意味着代码中没有问题。现在,我们正在转向其他推送通知服务,但是我非常想知道这里出了什么问题。