【问题标题】:With Firestore and Firebase cloud functions, how do you iterate over documents with a specific ID nested into a subcollection?使用 Firestore 和 Firebase 云函数,您如何迭代嵌套在子集合中的具有特定 ID 的文档?
【发布时间】:2020-11-10 11:12:31
【问题描述】:

使用的堆栈是:

  • Firestore
  • Firebase 云函数
  • 打字稿
  • 监听文档更改

我们的每个用户都有一份他收藏的帖子的副本:

user/{userId}/favorites/{postId}

当我们编辑帖子时,会触发一个函数并通过我们的活跃用户迭代以更新收藏夹中具有相同 postId 的帖子。

我的想法是迭代用户

const modifiedPostId = ourModifiedPost.id // from listener
const await activeUsers = firebase.db.collection('users').where('active','==',true).get()

for (const user of activeUsers) {
    const await samePostIdUserFavorite = firebase.db.collection(`users/${user.id}/favorites/${modifiedPostId}`).get()
    if (samePostIdUserFavorite.exists) {
         await copyPostToUserPosts(user, modifiedPostId)
    }
}

问题在于只有部分用户收藏了它,因此我们无偿进行大量阅读。

我很难用另一种方式,但我找不到如何限制对活跃用户的搜索,我什至不确定它是否可以工作?!?

const modifiedPostId = ourModifiedPost.id // from listener

// I'm calling a collection but actually get one document in a specific sub-collection from all parent collections...
// I don't see how this could work at all
const sameIdFavorites = firebase.db.collection(`users/{userId}/favorites/${modifiedPostId}`)}.get()

for (const favorite of sameIdFavorites) {
    // I have no idea how to get userID
    await copyPostToUserPosts(userId, modifiedPostId)
}

有没有办法只感染 'users/{userId}/favorites/{favoriteId}' 的帖子,其中 user.active === true 和 favoriteId === modifiedPostId?

或者在列表中只满足最后一个条件:favoriteId === modifiedPostId而不读取整个用户数据库?

谢谢

【问题讨论】:

    标签: typescript firebase google-cloud-firestore nosql google-cloud-functions


    【解决方案1】:

    有没有办法只感染来自“users/{userId}/favorites/{favoriteId}”的帖子,其中 user.active === true 和 favoriteId === modifiedPostId?

    使用您当前的架构,不,这是不可能的。 Firestore 不支持集合之间的类似 SQL 的连接,即使它们彼此嵌套。查询一次只能考虑单个集合(或集合组)中的文档内容。

    您可以将“活动”标志复制到“收藏夹”中的每个嵌套文档中,然后将其用作那里的过滤器。在不支持连接的 NoSQL 类型数据库中,这样的重复数据相当常见。

    或者在列表中只满足最后一个条件: favoriteId === modifiedPostId 而不读取整个用户数据库?

    再次使用您当前的架构,不。

    您可以改为将每个收藏夹文档的 ID 作为一个字段包含在该文档中,然后将其用作收藏夹collection group query 中的过滤器。

    假设“id”字段包含“favorites”的每个文档中的文档ID:

    firebase.db.collectionGroup("favorites").where("id", "==", modifiedPostId)
    

    这将为您提供所有名为“收藏夹”的子集合中的所有文档,这些文档的 ID 为modifiedPostId

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 2022-01-17
      相关资源
      最近更新 更多