如何遍历 Firebase Firestore 文档数组并将值推入数组

How to loop through an array of Firebase Firestore documents and push values into array

我正在 node.JS 中编写一个 Firebase Cloud Function,它从 Firebase Firestore 读取用户数据。 我无法将令牌值推送到令牌数组中,并且 return 函数末尾的所有令牌。我的代码如下:

function getTokens(subscribers) {
    return new Promise(async function (resolve, reject) {
        const tokenArray = [];
        subscribers.forEach(async (subscriber) => {
            await firestore
                .collection('users')
                .doc(subscriber)
                .get()
                .then((user) => {
                    console.log("Getting user data for user: ", user);
                    const tokens = user.data().tokens;
                    if (tokens) {
                        tokens.forEach((token) => {
                            console.log("Adding token to token array"); // data is available here but does not push into tokenArray
                            tokenArray.push(token);
                        });
                    }
                }).catch((error) => { console.error(error); reject(error); });
        });
        console.log("Token Array -- Final: ", tokenArray);
        resolve(tokenArray);
    });
};

您不能在 forEach 循环中使用 async-await。尝试映射一组承诺,然后使用 Promise.all(),如下所示:

function getTokens(subscribers) {
  return new Promise(async function (resolve, reject) {
    
    const subscribersDocs = await Promise.all(
      subscribers.map((subscriber) => {
        return firestore.collection("users").doc(subscriber).get();
      })
    );


    const tokenArray = subscribersDocs.reduce((acc, curr) => {
      const tokens = curr.data().tokens;
      if (tokens) {
        acc = acc.concat(tokens);
      }
      return acc;
    }, []);

    console.log("Token Array -- Final: ", tokenArray);
    resolve(tokenArray);
  });
}

同时结帐:

OP代码可以更正,更简洁如下:

async function getTokens(subscribers) {
  const getUser = subscriber => firestore.collection('users').doc(subscriber).get();
  const promises = subscribers.map(getUser);
  const users = await Promise.all(promises);
  return users.map(user => user.data().tokens).flat()
}

一些注意事项:

  • 将函数修饰为 async,因为它包含一个 await
  • 不要使用 Promise.new() 创建任何额外的承诺,Firestore 的 get() returns 承诺
  • map 收集 get 个承诺,用 Promise.all()
  • 运行 个承诺
  • 映射结果用户的 data.tokens 生成数组数组。把它压平就大功告成了。
  • 一个只抛出的catch,就像没有抓住一样