【问题标题】:How do I access the value returned by promise firestore?如何访问 promise firestore 返回的值?
【发布时间】:2022-01-04 04:57:16
【问题描述】:

我正在尝试访问 secondSnapshot.data() 返回的内容,但遇到了问题,如下面的 cmets 所述。我试图创建一个异步函数,但无济于事。知道出了什么问题吗? 请查看 2 cmets。

  useEffect(() => {
    firestore.collection(`comments`).onSnapshot((snapshot) => {
      const posts = snapshot.docs
        .map((doc) => {
          const address = doc.data().comments?.map((comment) => {
            comment.get().then((secondSnapshot) => {
              console.log("snapshot", secondSnapshot.data());

              #I SEE WHAT I EXPECT TO SEE

              return secondSnapshot.data();
            });
          });
          console.log(address) #THIS RETURNS UNDEFINED FOR SOME REASON??

          return {
            username: doc.data().username,
            date: doc.data().date.seconds,
            text: doc.data().text,
            votes: doc.data().votes,
            comments: [],
          };
        });
      props.setComments(posts);
    });
  }, [location]);

【问题讨论】:

  • 不要将你的 firestore 逻辑与你的 react 组件纠缠在一起。请参阅this Q&A 了解如何将事物分开的示例。

标签: javascript reactjs google-cloud-firestore async-await promise


【解决方案1】:

除了@Mulan 指出的 React 与 Firebase 设计问题之外,您的代码还有几个问题。

问题 #1

以下地图函数不返回任何内容。如果您不从该块返回某些内容,您将不会在地址中找到任何内容。

const address = doc.data().comments?.map((comment) => {
/* This MUST return something */
});

问题 #2

您正在混合同步和异步代码。基本上,您尝试在对 comment.get() 的不同异步调用完成运行之前打印地址值。

const address = doc.data().comments?.map((comment) => {
/* async code inside */
});
console.log(address); // this runs without waiting for the async code

建议

如果您对旧的 Promise 语法有困难,请尝试使用 async / await 代替:

firestore.collection(`comments`).onSnapshot(async (snapshot) => {
    const postPromises = snapshot.docs
        .map(async (doc) => {
            const comments = doc.data().comments ?? []; // assign an empty array if there are no comments
            const secondSnapshots = await Promise.all(comments.map((comment) => comment.get()));
            const addresses = secondSnapshots.map((secondSnapshot) => secondSnapshot.data());
            console.log(addresses);
            return { /* ... */ };
        });
    const posts = await Promise.all(postPromises);
    props.setComments(posts);
});

我不确定您是否应该在 onSnapshot 中调用 comment.get(),但这是另一回事,我不是 Firebase 专家。

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    相关资源
    最近更新 更多