【问题标题】:Firebase Cloud Functions - Cannot read property 'forEach' of undefinedFirebase Cloud Functions - 无法读取未定义的属性“forEach”
【发布时间】:2018-07-28 13:49:32
【问题描述】:

我有这样的事情:

const promises = [];

    l = niz.length;
    for (i = 0; i < l; i++) {
      if(niz[i].length === 0) {
          continue;
      }

      promises.push(admin.messaging().sendToDevice(niz[i], payload, options));
    }

   return Promise.all(promises).then((response) => {
        return cleanupTokens(response, tokens);
        //return resolve(); 
    }).then(() => {
        return resolve();
    });

但我总是在 firebase 日志中崩溃:

TypeError:无法读取未定义的属性“forEach” 在 cleanupTokens (/user_code/index.js:193:20) 在 Promise.all.then (/user_code/index.js:169:20) 在 process._tickDomainCallback (internal/process/next_tick.js:135:7)

回复是:

响应:[{结果:[[对象]], canonicalRegistrationTokenCount: 0, 失败计数:0, 成功计数:1, 多播ID:5591935326806715000 } ]

响应:未定义

清理是:

function cleanupTokens(response, tokens) {

// For each notification we check if there was an error.
const tokensToRemove = {};

console.log('response: ', response);

console.log('response: ', JSON.stringify(response.results));

response.results.forEach((result, index) => {
       const error = result.error;

       if (error) {
         console.error('Failure sending notification to', tokens[index], error);

         // Cleanup the tokens who are not registered anymore.
         if (error.code === 'messaging/invalid-registration-token' ||
             error.code === 'messaging/registration-token-not-registered' ||
             error.code === 'messaging/invalid-recipient') {

           tokensToRemove[`/tokens/${tokens[index]}/g`] = null;
           tokensToRemove[`/tokens/${tokens[index]}/l/0`] = null;
           tokensToRemove[`/tokens/${tokens[index]}/l/1`] = null;
         }
       }
   });

   return admin.database().ref().update(tokensToRemove);
}

对清理令牌有帮助吗?

【问题讨论】:

  • 看起来response.results 不是一个数组。您能否将console.log('response: ', response.results); 替换为console.log('response: ', JSON.stringify(response.results)); 并将该日志添加到您的问题中。
  • 当然,它是未定义的
  • 有趣,因为您的原始日志显示 results: [ [Object] 这似乎表明 results 是一个数组。但如果是undefined,您应该在调用forEach 之前检查它。所以if (response.results) { response.results.forEach(...

标签: node.js firebase google-cloud-functions


【解决方案1】:

您选择将每个通知分别发送给每个用户,使响应“包装”为一个单一的响应,并且每个响应本身也是一个单一的 - 访问起来很奇怪(response[0].results.foreach 应该可以工作)

但即便如此,您也只需要处理 1 个项目,因为您已将每个通知单独发送。我相信对所有相关令牌发出 1 次 sendToDevice() 请求会更有效,而不是单独发送它们。

考虑将您的第一个代码更改为:

//const promises = [];
var tokens = [];

l = niz.length;
for (i = 0; i < l; i++) {
  //if(niz[i].length === 0) {
  if(niz[i].length > 0) //I guess those are your relevant tokens
      tokens.push(niz[i]); //Fill in the relevant tokens
}

//promises.push(admin.messaging().sendToDevice(niz[i], payload, options));

return admin.messaging().sendToDevice(tokens, payload, options)
.then(response => {
    return cleanupTokens(response, tokens);
})
.then(() => {
    return resolve();
});

//return Promise.all(promises).then((response) => {
//    return cleanupTokens(response, tokens);
//    //return resolve(); 
//}).then(() => {
//    return resolve();
//});

在此更改之后,您的其余代码应该可以工作。

(@Frank 的评论很少归功于他的评论 - JSON 日志有助于确定问题)

编辑:

关于您的评论,如果每个 niz[i] 项目本身就是一个数组,您可以这样做:

const promises = [];

l = niz.length;
for (i = 0; i < l; i++) {
  if(niz[i].length === 0) {
      continue;

  //promises.push(admin.messaging().sendToDevice(niz[i], payload, options));

  var newPromise = return admin.messaging().sendToDevice(niz[i], payload, options)
  .then(response => {
    return cleanupTokens(response, tokens);
  })
  .then(() => {
      return resolve();
  });

  promises.push(newPromise);

}

return Promise.all(promises);

//return Promise.all(promises).then((response) => {
//    return cleanupTokens(response, tokens);
//    //return resolve(); 
//}).then(() => {
//    return resolve();
//});

【讨论】:

  • sendToDevice 每个请求的限制为 1000,因此我将令牌分成大小为 999 的数组 ...
  • 您的代码有效!谢谢!现在,我必须走了,会回来几个小时:)
  • 我认为关于发送的最后一个代码是错误的,因为令牌数组可以超过 1000 个,并且 sendToDevice 每个请求的限制为 1000 个......
  • 之前你说过你将每个内部数组分成 999 的大小......所以假设它应该可以工作
  • 我认为令牌应该在 sendToDevice 中替换为 niz[i],否则 niz[i] 永远不会被使用?顺便说一句,“niz”是“数组”,但在塞尔维亚语中:)
猜你喜欢
  • 2019-09-28
  • 2021-04-29
  • 1970-01-01
  • 2021-01-17
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多