我想访问文档中的集合。我想访问具有特定postId的posts集合中的文档,但是在该文档中有一个称为注释的集合,我想访问该集合。我不认为我所做的代码是正确的。
const fetchComments = async() => {
const posts = doc(db, 'posts', postId);
const comment_list = collection(posts, "comments");
const snapshot = await getDocs(comment_list);
setComments(snapshot.docs.map((doc) => {
doc.data();
}));
}数据库截图:


发布于 2021-10-16 07:05:45
在map函数中,您不会返回文档的数据。
setComments(snapshot.docs.map((doc) => {
doc.data(); // <-- not returned!
}));这意味着您在帖子上的注释数量一样多,您只会得到一个长度为这个长度的空数组。即3注释-> setComments([undefined, undefined, undefined])
您可以通过将该指令重写为以下内容之一来解决此问题:
setComments(snapshot.docs.map((doc) => {
return doc.data()
}));setComments(snapshot.docs.map(
(doc) => doc.data()
));setComments(snapshot.docs.map((doc) => doc.data()))但是,在处理注释数组时,还应该返回数据中每个注释的文档ID,以便将其用作key for rendering。
setComments(snapshot.docs.map(
(doc) => ({ key: doc.id, ...doc.data() })
));其他注释
而不是同时使用doc()和collection()
const posts = doc(db, "posts", postId);
const comment_list = collection(posts, "comments");您可以单独使用collection():
const comment_list = collection(db, "posts", postId, "comments");这会将您的功能转换为:
const fetchComments = async () => {
const comment_list = collection(db, "posts", postId, "comments");
const snapshot = await getDocs(comment_list);
setComments(snapshot.docs.map(
(doc) => ({ key: doc.id, ...doc.data() })
));
}为了使其在React中更安全,您应该将其包装在一个useEffect中,以确保一旦您拥有数据,调用setComments仍然有效。
useEffect(() => {
let unsubscribed = false;
if (!postId) {
console.error(`Failed to load post comments! postId (${postId}) was falsy`);
setComments(null);
setLoading(false);
setErrorMessage("Invalid post ID");
return;
}
const comment_list = collection(db, "posts", postId, "comments");
setLoading(true);
getDocs(comment_list)
.then((comment_list_snapshot) => {
if (unsubscribed) return; // silently discard, outdated
setComments(comment_list_snapshot.docs.map(
(doc) => ({ key: doc.id, ...doc.data() })
));
setErrorMessage(null);
setLoading(false);
})
.catch((err) => {
if (unsubscribed) return; // silently discard, outdated
console.error("Failed to load post comments!", err);
setComments(null);
setErrorMessage("Comments could not be loaded.");
setLoading(false);
});
return () => unsubscribed = true;
}, [db, postId]);由于上面的块看起来与大多数Firestore调用相同,除了设置什么数据外,还可以考虑使用Firebase钩子库,或者编写自己的库,这样就可以将其全部平铺成如下所示:
const [ comments_docs, comments_loading, comments_error ] = useFirestoreCollection(db, "posts", postId, "comments")
if (comments_loading)
return null; // hide until loaded
if (comments_error) {
console.error("Failed to load comments: ", comments_error);
return (<div class="error">Could not load comments</div>)
}
const comments = comments_docs.map((doc) => ({ key: doc.id, ...doc.data() }));
return ({
comments.map((commentData) => {
return <Comment
key={commentData.key}
author={commentData.author}
content={commentData.content}
...
/>
})
});发布于 2021-10-16 04:22:06
根据您的问题,第一个集合是posts,id与228.一起看,子集合是注释。通过替换值来尝试下面的代码。
db.collection('FirstCollection/' + id + '/DocSubCollectionName').get().then((subCollectionSnapshot) => {
subCollectionSnapshot.forEach((subDoc) => {
console.log(subDoc.data());
});
});
https://stackoverflow.com/questions/69592106
复制相似问题