Firebase Cloud Functions-无法读取未定义的属性“ forEach”

时间:2018-07-28 13:49:33

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

我有这样的东西:

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,       failureCount:0,       successCount:1       multicastId: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);
}

对清理令牌有帮助吗?

1 个答案:

答案 0 :(得分:0)

您选择将每个通知分别发送给每个用户,从而使响应成为“包装”为单身的响应,并且每个响应本身也是单身的-使其访问很奇怪(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();
//});