【问题标题】:Firestore subcollection querying and applying Firestore rulesFirestore 子集合查询和应用 Firestore 规则
【发布时间】:2018-07-14 17:01:34
【问题描述】:

情况:

我正在创建一个基本上如下所示的数据结构:

events:
  adminUserId: 1337
  users:
    questiongroups:
      questions:
        text: 'foo',
        value: 42

所以 events 是一个列表,每个事件的用户、每个用户每个事件的问题组以及每个用户每个事件的每个问题组的问题也是如此。其中一些有额外的字段,如 ID 等,但为了简单起见,我省略了它们。

这个数据结构很好,因为我可以限制访问,只允许用户操作他们自己的问题组列表和问题子列表 - 使用 firestore 规则。

问题:

每个事件都有一个管理员用户,该用户应该能够对他作为管理员的所有数据进行 CRUD(通过 adminUserId)。或者更准确地说,他应该能够在他的 UI 中的一张大表中看到所有关于一个事件的数据。这是一个小规模的应用程序,大约有 20 个用户,可能有 50 个问题组,平均有 5 个问题。所以基本上是这样的:

        | QuestionGroup1_Question1 | QuestionGroup1_Question2 | QuestionGroup2_Question1
user #1 | foo                      | bar                      | 1337
user #2 | foo                      | bar                      | 1701

现在我希望能够以最少的查询(可能只有一个)查询一个事件的数据。 但从我目前收集到的信息来看,您只能在 Firestore 上执行浅查询,因此我只能检索“事件”的字段,但随后必须查询每个用户,然后查询每个问题组,然后再次查询每个问题 - 即使数量如此之少,也将构成大量查询。

所以基本上我的问题是:我在这里有什么选择? 我读过可以在文档中嵌套复杂的对象。但是根据https://firebase.google.com/docs/firestore/manage-data/structure-data,您无法查询它们,那么我还能通过对它们的 Firestore 规则限制访问吗?我发现你可以在使用 Firebase 实时数据库时使用通配符来做到这一点,但是 Firestore 呢?

我很乐意了解一些选项。 谢谢!

【问题讨论】:

  • 这个范围很广。听起来你正在进入一个可能有很多讨论可能性的对话。发布到 firebase-talk 可能更适合这种讨论。 groups.google.com/forum/#!forum/firebase-talk
  • 基本上我的问题是我是否会采用嵌套数据方法 - 比如 "event_1":{ "user_1":{...}, "user_2": {...}} -我还能对他们应用 Firestore 规则吗?就像只允许特定用户本人和管理员访问用户数据一样 - 因为我不能只查询特定事件并获取其所有子数据

标签: angular firebase google-cloud-firestore angular5


【解决方案1】:

回答您的问题:

你能查询嵌套数据吗?是的

您可以查询嵌套数据,但不能查询嵌套列表。您可以在仍然使用对象的同时模仿列表(即{ 0: 'first', 1: 'second' }),但我不建议这样做。

这是一个查询嵌套数据的例子:
db.collection('questions').where('topic.coding', '==', true)

您可以对嵌套数据强制执行规则吗?否(用于读取)

您不能对 Firestore 文档内的嵌套数据强制执行读取规则。这需要能够使用 select(目前仅在 firebase-admin 中可用)并且能够在类似于 request.query(request) 的规则中查看请求信息。

编辑:另外,是的(用于写入)
您可以对所有数据(包括嵌套对象和列表)强制执行写入规则以进行写入。由于您可以看到写入的整个有效负载 (request.resource),因此您可以制定规则来确定哪些路径是可覆盖的和/或根据文档或数据库中的其他数据允许哪些值。

我的建议

扁平化您的数据库结构。比如:

match /events/{event_id} {
  match /users/{user_id} {
  }
  match /groups/{group_id} {
  }
  match /questions/{question_id} {
    // check if request.auth.uid is creator
  }
}

我不确定每个文档中的内容,因此我无法确定实现 Firestore 结构以优化查询和简化规则的最佳方式。

由于 Firestore 规则不像 Firebase 的 RTDB 规则那样级联,因此扁平化结构根本不会使您的规则复杂化。唯一的缺点(我认为是一个优点)是需要为扁平集合上的非浅层查询建立索引(即用户希望查看他们关于“编码”主题的所有问题)。

我的最终建议是找出所有可能的查询约束(即 user_id、topic、group_id),确定哪些是强制性的(可能是 user_id 和/或group_id)和基于强制约束的嵌套集合(即 /users/{user_id}/questions/{q_id} 如果“user_id”对于查询问题是必需的)。对于规则,您始终可以只向需要安全的文档添加一个子集合,其中不包含任何内容(或角色/权限信息),子集合中的文档 ID 与请求用户的 ID (即安全文档)匹配必须具有适当的角色/权限才能访问父文档)

这并不能解决设计数据库结构时的所有问题,但它是一个很好的起点,有助于识别“自然分层”(Choose a Data Structure) 数据。

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 2018-11-27
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多