我正在尝试创建主根集合中包含的所有文档的列表。
我有这样的数据:
collection -> doc -> collection -> doc
const [posts, setPosts] = useState();
useEffect(() => {
const db = firebase.firestore();
return db.collection('posts').onSnapshot((snapshot) => {
const postData = [];
snapshot.forEach((doc) => postData.push({ ...doc.data(), id: doc.id }));
setPosts(postData);
});
}, []);
console.log(posts);
但是当它应该是2个对象的数组时,这只会记录一个空数组。
任何人都可以向我阐明我要去哪里的地方吗?如果我能够通过此操作访问嵌套数据?
答案 0 :(得分:2)
我们可以看到,在Firebase控制台中,父posts
集合中的文档显示为斜体:这是因为这些文档仅在控制台中显示(在控制台中)一个或多个子集合的“容器”,但它们不是“真正的”文档。
事实上,如果您直接在col1
集合下创建具有完整路径doc1/subCol1/subDoc1
的文档,则不会创建任何中间文档(即没有doc1
文档)。 / p>
Firebase控制台以斜体显示这种“容器”(或“占位符”),以“具体化”层次结构,并允许您导航到subDoc1
文档,但doc1
文档< strong>在Firestore数据库中不存在。
让我们举个例子:想象一个doc1
集合下的col1
文档
col1/doc1/
和subDoc1
(子)集合下的另一个subCol1
col1/doc1/subCol1/subDoc1
实际上,从技术角度来看,它们根本不相关。他们只是分享自己的道路的一部分而已。这样做的副作用是,如果删除文档,则该文档的子集合仍然存在。
因此,在进行db.collection('posts').onSnapshot((snapshot) => {...})
时得到一个空数组是正常的,因为您正在侦听不存在的文档。
您可以做的是监听posts
子集合之一中的文档,如下所示:
db.collection('posts').doc('frlGy...').collection('posts').onSnapshot((snapshot) => {...});
另一种可能性是使用Collection Group query,以获取所有posts
子集合中的所有元素。但是在这种情况下,您不能让父集合和子集合具有相同的名称(即posts
)。
例如,如果我希望能够 记录所有用户的所有帖子,因为从技术上讲,用户文档不会 存在吗?
这完全取决于您是否有一些user
文档,这还不清楚。
如果这样做,则为每个user
文档创建一个posts
子集合,并使用db.collection('Users').doc(user.uid).collection('posts').onSnapshot((snapshot) => {...});
您还可以使用集合组查询来查询不同的posts
子集合。
如果没有user
文档,则可以有一个全局posts
集合(根集合),并将用户uid
保存为每个{{1} }文件。这样,您可以保护它们(使用安全性规则),还可以按用户查询所有帖子。您还可以轻松地在所有用户中查询帖子。
您需要将post
放在回调中,如下所示:
console.log
还要注意,这只会返回const [posts, setPosts] = useState();
useEffect(() => {
const db = firebase.firestore();
return db.collection('posts').onSnapshot((snapshot) => {
const postData = [];
snapshot.forEach((doc) => postData.push({ ...doc.data(), id: doc.id }));
console.log(postData); // <------
setPosts(postData);
});
}, []);
文档,而不返回子集合中的文档:如上所述,Firestore查询很浅。如果要查询子集合,则需要执行其他查询。