如何在 Cloud Firestore 查询中加入多个文档?

新手上路,请多包涵

我有一个具有以下结构的 Cloud Firestore 数据库:

  • 用户
    • [uid]
      • 名称:“测试用户”
  • 帖子
    • [ID]
      • 内容:“只是一些测试帖子。”
      • 时间戳:(2017 年 12 月 22 日)
      • uid:[uid]

实际DB中存在更多数据,上面只是说明了集合/文档/字段结构。

我在我的网络应用程序中有一个视图,我在其中显示帖子并希望显示发帖用户的姓名。我正在使用以下查询来获取帖子:

 let loadedPosts = {};
posts = db.collection('posts')
          .orderBy('timestamp', 'desc')
          .limit(3);
posts.get()
.then((docSnaps) => {
  const postDocs = docSnaps.docs;
  for (let i in postDocs) {
    loadedPosts[postDocs[i].id] = postDocs[i].data();
  }
});

// Render loadedPosts later

我想做的是通过存储在帖子的uid字段中的uid查询用户对象,并将用户的姓名字段添加到相应的loadedPosts对象中。如果我一次只加载一个帖子,这没问题,只需等待查询返回一个对象,然后在 .then() 函数中对用户文档进行另一个查询,依此类推。

但是,因为我一次获得多个帖子文档,所以我很难弄清楚如何在调用 .get() 在每个帖子的 user/[uid] 之后将正确的用户映射到正确的帖子文档由于他们返回的异步方式。

谁能想出一个优雅的解决方案来解决这个问题?

原文由 saricden 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 265
2 个回答

我会进行 1 个用户文档调用和所需的帖子调用。

 let users = {} ;
let loadedPosts = {};
db.collection('users').get().then((results) => {
  results.forEach((doc) => {
    users[doc.id] = doc.data();
  });
  posts = db.collection('posts').orderBy('timestamp', 'desc').limit(3);
  posts.get().then((docSnaps) => {
    docSnaps.forEach((doc) => {
    loadedPosts[doc.id] = doc.data();
    loadedPosts[doc.id].userName = users[doc.data().uid].name;
  });
});

原文由 parmigiana 发布,翻译遵循 CC BY-SA 3.0 许可协议

这对我来说似乎很简单:

 let loadedPosts = {};
posts = db.collection('posts')
          .orderBy('timestamp', 'desc')
          .limit(3);
posts.get()
.then((docSnaps) => {
  docSnaps.forEach((doc) => {
    loadedPosts[doc.id] = doc.data();
    db.collection('users').child(doc.data().uid).get().then((userDoc) => {
      loadedPosts[doc.id].userName = userDoc.data().name;
    });
  })
});

如果你想防止多次加载用户,你可以缓存用户数据客户端。在那种情况下,我建议将用户加载代码分解为辅助函数。但这将是上述的变体。

原文由 Frank van Puffelen 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题