这个让我难倒了好几天。有很多代码,所以我希望你能坚持我。
我已经将您在下面看到的所有代码编译到一个地方,以使其更容易:
https://stackblitz.com/edit/angular-us7xwt
好的,让我们开始吧!
我每天运行一个 cron 作业,当用户有新音乐时通知他们,以检查哪个触发了 firebase 函数。要查询我的网站 API 发布,请返回一个对象数组,其中包含今天发布音乐的用户和他们关注的艺术家:
触发Firebase 函数后运行的 API 调用
axios.get(`${apiURL}...`).then((response) => {
var users = response.data;
if(users.length > 0) {
createTopics(users)
}
})
从此 API 调用返回的数据的格式如下,并存储在上面的users
变量中。如果数组已填充,我将运行createTopics(users)
[{
"userUID": "kaLOIkGwrWO4DSFP41OmfozxhsN2",
"artists": [
"Adventure Club",
"LSD",
"Marshmello"
]
},
{
"userUID": "ZvOBNBqxbgRYoibSYEwkL9YKtWG2",
"artists": [
"Krewella",
"Lolo Zouaï",
"The Chemical Brothers"
]
}]
创建主题()
这将为每个用户的推送通知生成元数据。创建消息后,我需要查询特定用户拥有的所有设备,以便使用 Firebase 的multicast()
向所有设备推送通知
function createTopics(users) {
users.forEach((user: any) => {
const message = {
notification: {
title: `my title`,
body: `my body`
},
tokens: null
}
// tslint:disable-next-line:no-floating-promises
findUserDevices(user.userUID, message);
})
}
查找用户设备()
此函数在我的 firestore 数据库中查询发送推送通知所需的特定用户的设备令牌。如果该用户的数据库中存在设备,我们需要将消息推送到他们的设备。
function findUserDevices(uid: string, message) {
collectionData(fb.firestore().collection('devices').where('userId', '==', uid)).pipe(
filter((userDevices) => userDevices && userDevices.length > 0),
take(1)
).subscribe((devices: any) => {
var userDeviceTokens: string[] = devices.map((device: any) => device.token);
console.log(userDeviceTokens)
if (userDeviceTokens !== undefined && userDeviceTokens.length != 0) {
// tslint:disable-next-line:no-floating-promises
pushToDevices(userDeviceTokens, message);
}
})
}
推送到设备()
以下是将消息推送到设备的异步函数...也许这就是事情出错的地方??我将令牌附加到payload
然后使用sendMulticast()
.在此方法的响应中,如果任何令牌失败,我使用deleteOldToken()
异步调用将其删除。
async function pushToDevices(userDeviceTokens, payload) {
payload['tokens'] = userDeviceTokens;
await admin.messaging().sendMulticast(payload).then((response) => {
console.log('Success:', response);
if (response.failureCount > 0) {
const failedTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
failedTokens.push(userDeviceTokens[idx]);
}
});
failedTokens.forEach((token) => {
var tokenInstanceID = token.split(':')[0];
// tslint:disable-next-line:no-floating-promises
deleteOldToken(tokenInstanceID);
})
}
})
.catch((error) => {
console.log('Error:', error)
});
}
删除旧令牌()
async function deleteOldToken(tokenInstanceID) {
await fb.firestore().collection('devices').doc(tokenInstanceID).delete().then(() => {
console.log(`Token ${tokenInstanceID} deleted`)
})
}
这就是整个方法,这是我的日志
查看我的控制台日志,我看到混合了奇怪的活动,并有几行超时错误
Error: { Error: Error while making request: timeout of 10000ms exceeded.
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:122:28)
at /user_code/node_modules/firebase-admin/lib/utils/api-request.js:152:23
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
errorInfo:
{ code: 'app/network-timeout',
message: 'Error while making request: timeout of 10000ms exceeded.' },
codePrefix: 'app' }
混合了几行连接重置错误:
Error: { Error: Error while making request: read ECONNRESET. Error code: ECONNRESET
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:122:28)
at /user_code/node_modules/firebase-admin/lib/utils/api-request.js:154:19
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
errorInfo:
{ code: 'app/network-error',
message: 'Error while making request: read ECONNRESET. Error code: ECONNRESET' },
codePrefix: 'app' }
最后,有些工作完美:
Success: { responses:
[ { success: true,
messageId: 'projects/release-hub-f3f5f/messages/1555102845415084' },
{ success: true,
messageId: 'projects/release-hub-f3f5f/messages/0:1555102845414983%f95cf250f95cf250' } ],
successCount: 2,
failureCount: 0 }
在联系我的一些用户后,有几个人收到了他们的推送通知,而许多人没有。我有一种预感,这与我的异步调用有关,但我哪里出错了?非常感谢您坚持这个问题,如果您需要更多信息,请告诉我。
var message = new MulticastMessage()
{
Tokens = clientTokens,
Data = new Dictionary<string, string>()
{
{"title", title},
{"body", body},
},
Notification = new Notification()
{
Title = title ,
Body = body
}
};
var response = FirebaseMessaging.DefaultInstance.SendMulticastAsync(message).Result;
这对我有用