首页 > 解决方案 > 获取 Firebase 集合中的所有文档 - React

问题描述

我正在尝试创建包含在我的主根集合中的所有文档的列表。

我有这样的数据:

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 个对象的数组时记录一个空数组。

任何人都可以照亮我要去的地方吗?如果我能够通过这样做访问嵌套数据?

标签: javascriptreactjsfirebasegoogle-cloud-firestore

解决方案


在您的评论和屏幕截图添加后更新

我们可以看到父posts集合中的文档在 Firebase 控制台中以斜体字体显示:这是因为这些文档仅作为一个或多个子集合的“容器”存在(在控制台中),但它们不是“真正的”文件。

事实上,如果您直接在col1具有完整路径的集合下创建文档,则doc1/subCol1/subDoc1不会创建中间文档(即没有doc1文档)。

Firebase 控制台以斜体显示这种“容器”(或“占位符”),以便“实现”层次结构并允许您导航到subDoc1文档,但doc1文档在 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) => {...});

另一种可能性是使用集合组查询,以获取所有posts子集合中的所有元素。但是在这种情况下,您不能让父集合和子集合共享相同的名称(即posts)。


在您的第二条评论之后更新

例如,如果我希望能够记录所有用户的所有帖子,因为用户文档在技术上不存在,我是否需要采取不同的做法?

这完全取决于您是否有一些user文件,这不清楚。

如果你这样做,对于每个user文档,创建一个posts子集合,并使用db.collection('Users').doc(user.uid).collection('posts').onSnapshot((snapshot) => {...});

您还可以使用集合组查询来查询不同的posts子集合。

如果您没有user文档,您可以拥有一个全局posts集合(根集合)并将用户保存uid为每个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);
    });
  }, []);

另请注意,这只会返回frlGy...文档,而不是子集合中的文档:如上所述,Firestore 查询很浅。如果要查询子集合,则需要执行额外的查询。


推荐阅读