【问题标题】:Get all documents in Firebase collection - React获取 Firebase 集合中的所有文档 - React
【发布时间】:2020-05-05 14:19:04
【问题描述】:

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

我有这样的数据:

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

谁能指出我哪里出错了?如果我能够通过这样做访问嵌套数据?

【问题讨论】:

  • 您能显示您的数据库的屏幕截图吗?请注意,Firestore 查询很浅。
  • 好的,刚刚添加

标签: javascript reactjs firebase google-cloud-firestore


【解决方案1】:

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

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

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

Firebase 控制台以斜体显示这种“容器”(或“占位符”),以便“具体化”层次结构并允许您导航到 subDoc1 文档,但 doc1 文档没有t 存在于 Firestore 数据库中

举个例子:想象一下col1集合下的doc1文档

col1/doc1/

另一个subDoc1subCol1(子)集合下

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 保存为每个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 查询很浅。如果要查询子集合,需要执行额外的查询。

【讨论】:

  • 感谢 Renaud,但它仍然只记录一个空数组。我添加了一个图像来显示根级别的数据。
  • 啊,好吧,有道理。感谢您的解释!抱歉,我是 firebase 新手,所以还是习惯了。因此,如果我试图建立一个数据结构,例如:Users -> docs ->posts -> docs,我不应该这样做:db.collection('Users').doc(user.uid).collection('posts ').add();?
  • 在这种情况下,是的,您可以很好地做到这一点:db.collection('Users').doc(user.uid).collection('posts').onSnapshot((snapshot) =&gt; {...}); 将完美运行
  • 但这不只是创建一个斜体容器文档吗?例如,如果我希望能够记录所有用户的所有帖子,因为用户文档在技术上不存在,我是否需要采取不同的做法?
【解决方案2】:
   const getMarkers= async ()=> { 
        await db.collection('movies').get()
          .then(querySnapshot => {
            querySnapshot.docs.forEach(doc => {
            setlist(doc.data().title);
          });
        });
      }

很简单,只需在函数上添加 async 和 await 并在 useeffect

中调用该函数

【讨论】:

    猜你喜欢
    • 2021-07-01
    • 2021-05-09
    • 2020-10-15
    • 2023-03-28
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多