【问题标题】:How to use Promise.all with multiple Firestore queries如何将 Promise.all 与多个 Firestore 查询一起使用
【发布时间】:2021-09-01 09:08:15
【问题描述】:

我知道在堆栈溢出方面有类似的问题,但到目前为止没有人能够帮助我让我的代码正常工作。

我有一个接受 id 的函数,并调用 firebase firestore 以获取“feedItems”集合中的所有文档。每个文档包含两个字段,一个时间戳和一个帖子 ID。该函数返回一个包含每个帖子对象的数组。这部分代码(下面的 getFeedItems)按预期工作。

问题出现在下一步。一旦我有了帖子 ID 的数组,我就会遍历该数组并对每个数组进行一次 Firestore 查询,以获取实际的帖子信息。我知道这些查询是异步的,所以我使用 Promise.all 等待每个 Promise 解决,然后再使用最终的发布信息数组。

但是,由于这些循环查询,我继续收到“未定义”。 为什么?

const useUpdateFeed = (uid) => {
  const [feed, setFeed] = useState([]);
  useEffect(() => {
    // getFeedItems returns an array of postIDs, and works as expected
    async function getFeedItems(uid) {
      const docRef = firestore
        .collection("feeds")
        .doc(uid)
        .collection("feedItems");
      const doc = await docRef.get();
      const feedItems = [];
      doc.forEach((item) => {
        feedItems.push({
          ...item.data(),
          id: item.id,
        });
      });
      return feedItems;
    }

    // getPosts is meant to take the array of post IDs, and return an array of the post objects
    async function getPosts(items) {
      console.log(items)
      const promises = [];

      items.forEach((item) => {
        const promise = firestore.collection("posts").doc(item.id).get();
        promises.push(promise);
      });

      const posts = [];
      await Promise.all(promises).then((results) => {
        results.forEach((result) => {
          const post = result.data();
          console.log(post); // this continues to log as "undefined". Why?
          posts.push(post);
        });
      });

      return posts;
    }

    (async () => {
      if (uid) {
        const feedItems = await getFeedItems(uid);
        const posts = await getPosts(feedItems);
        setFeed(posts);
      }
    })();
  }, []);

  return feed; // The final result is an array with a single "undefined" element
};

我已经自己验证了几件事:

  • 我的 Firestore 查询一次完成一项时按预期工作(因此查询结构本身没有任何错误)。
  • 这是 React 的自定义钩子。我认为我对 useState/useEffect 的使用在这里没有任何问题,并且我已经使用模拟数据测试了这个钩子的实现。

编辑:请求了一个console.log() 项目并已添加到代码sn-p。我可以确认我尝试访问的 firestore 文档确实存在,并且在单个查询中(而不是循环中)调用时已成功检索。

此外,为简单起见,Firestore 上的集合目前仅包含一篇帖子(ID 为“ANkRFz2L7WQzA3ehcpDz”,可在下面的控制台日志输出中看到。

编辑二:为了使输出更清晰,我将其粘贴为下面的图像。

【问题讨论】:

  • 您能console.log(items) 检查Firestore 中是否存在具有这些ID 的文档吗?如果它记录未定义,那么可能是因为文档正在丢失
  • 请同时记录results
  • 嗨@Dharmaraj,我已经添加了请求的日志。另请注意,我已确认具有这些 ID 的文档确实存在于 Firestore 中,并且已通过单独的 firebase 查询成功检索到它们。 Firebase 查询循环不起作用。
  • [[Prototype]]: Array(0) 的日志是什么?看起来像一个空数组
  • @TarikHuber 为了更清楚,我添加了控制台日志的图像。第 81 行的日志与 getPosts() 中“项目”的控制台日志相关。第 93 行的日志是指 Promise.all 语句中的控制台日志。

标签: javascript firebase google-cloud-firestore es6-promise


【解决方案1】:

事实证明,这是人为错误。查看控制台日志输出,我意识到文档 ID 前面有一个空格。在后端删除它使我的代码工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 2019-05-27
    • 2017-11-25
    • 1970-01-01
    • 2021-03-01
    相关资源
    最近更新 更多