【问题标题】:Cloud Firestore - ensuring data consistencyCloud Firestore - 确保数据一致性
【发布时间】:2018-06-21 20:53:57
【问题描述】:

我的数据库使用冗余数据来加快获取速度并最大限度地减少某些查询需要读取的文档数量。例如,我会将关注用户的姓名存储在用户文档中的地图中,这样我就不必阅读另一个文档来检索每个关注用户的姓名。

User: (Collection) {
    userID: (Document) {

    //user state
    name: ...

    followingUsers: (Map) {
        followingUserID: nameOfUser,
        followingUserID: nameOfUser
    }
}

}

如果用户要更改他们的姓名,将这些更改传播到具有冗余数据的所有地方的最佳方法是什么?

【问题讨论】:

  • 好问题!不久前,我在this answer 中编写了 Firebase 实时数据库的基本方法。 White Firestore 是一个不同的数据库,方法可能是相同的。

标签: firebase google-cloud-firestore


【解决方案1】:

好问题! 对于初学者,我建议在服务器 SDK 或云功能中执行此类管理任务,因为您不希望客户端必须具有开始处理每个用户文档的能力。

好消息是,一旦您开始使用服务器 SDK,您就可以将查询放入事务中。因此,假设 user_123 将他们的名字从“Jenny”更改为“Jen”。您的交易在伪代码中看起来像这样:

  • 开始交易
    • transaction.get(usersRef.where("followingUsers.user_123", ">=", ""))
    • 循环查询结果。从每个文档中获取 doc_id 并使用它来开始构建事务中的写入。
      • transaction.update("/users/<doc_id>/", {"followingUsers.user_123" : "Jen"})
    • 还要确保添加transactions.update("/users/user_123", {"name": "Jen"})
  • 结束交易

这种通用方法也适用于客户端,但您无法在事务中执行此操作。 (不过,您仍然可以将所有这些更改放入批量写入中。)

【讨论】:

  • 感谢您的回答。我明白为什么授予客户端对其他用户文档的写入权限是一个坏主意,但假设为什么不能在客户端完成此事务?
  • 如果该操作不需要任何预先存在的数据的当前值,请使用batched write 而不是事务,因为它更简单且出现问题的机会更少。
  • 是的:事务(或批量)写入也可以从客户端完成。在这种情况下,您可能希望在安全规则中强制执行数据结构。虽然这是可能的,但通常比 Todd 建议的在 Cloud Functions 中做同样的工作要多(不熟悉)。
  • iCode,这不能在客户端完成的唯一原因是客户端 SDK 无法在事务内部执行查询。 (您只能读取单个文档)
猜你喜欢
  • 1970-01-01
  • 2021-01-22
  • 2021-05-26
  • 2011-03-10
  • 2021-05-06
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
相关资源
最近更新 更多