简体   繁体   中英

How do I access the value returned by promise firestore?

I'm trying to access what's returned by secondSnapshot.data(), but am having an issue, as described by the comments below. I tried to create an async function, but to no avail. Any idea what's going wrong? Please view the 2 comments.

  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]);

Besides the React vs Firebase design problem pointed by @Mulan, your code has several issues.

Issue #1

The following map function returns nothing. You won't find anything in address if you don't return something from this block.

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

Issue #2

You are mixing synchronous and asynchronous code. Basically, your attempt to print address value before the different async calls to comment.get() finished running.

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

Advice

If you are having a hard time with the old promise syntax, try using async / await instead:

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);
});

I'm not sure you should be calling comment.get() inside onSnapshot , but this is another story and I'm not a Firebase specialist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM