gpt4 book ai didi

firebase - 火存储 : How to query a map of roles inside a subcollection of documents?

转载 作者:行者123 更新时间:2023-12-02 02:08:23 34 4
gpt4 key购买 nike

我有以下子集合结构:

/projects/{projectId}/documents/{documentId}

其中每个文档都有一个用于检查每个文档的安全规则的访问映射:

{
title: "A Great Story",
content: "Once upon a time ...",
access: {
alice: true,
bob: false,
david: true,
jane: false
// ...
}
}

如何设置安全规则:

match /{path=**}/documents/{documentId} {
allow list, get: if resource.data.access[request.auth.uid] == true;
}

当我想查询 alice 可以跨所有项目访问的所有文档时:

db.collectionGroup("documents").where(`access.${uid}`, "==", true);

我收到一条错误消息,告诉我需要为 access.aliceaccess.david 等创建集合组索引。

如何通过集合组查询克服此索引问题?

最佳答案

作为索引的快速概述,有两种类型 - 复合索引(用于将多个字段连接在一起)或单字段索引。默认情况下,对于普通集合查询,会自动为文档的每个字段创建单字段索引;对于集合组查询,则会禁用单字段索引。如果字段的值是数组,则该数组的值将添加到Array Contains索引中。如果字段的值是原始值(字符串、数字、时间戳等),则文档将添加到该字段的升序和降序索引中。

启用 access 的查询对于集合组查询的字段,必须创建索引。虽然您可以单击进行查询时收到的错误消息中的链接,但这只会为您正在查询的用户添加索引(例如 access.aliceaccess.bob 等)。相反,您应该使用 Firebase Console告诉 Cloud Firestore 为 access 创建索引(这将为每个子级创建索引)。打开控制台后,使用“添加豁免”按钮(考虑使用“豁免”来表示“覆盖默认设置”)来定义新的索引规则:

在第一个对话框中,使用以下设置:

Collection ID:      "documents"
Field Path: "access"

Collection: Checked ✔
Collection group: Checked ✔

在第二个对话框中,使用以下设置:

<表类=“s-表”><标题>收集范围集合组范围 <正文>升序 已启用 已启用降序 已启用 已启用数组包含 已启用 已启用

在您的安全规则中,您还应该检查目标用户是否在 access 中在做平等之前先映射。访问丢失的属性时会抛出“对象上的属性未定义”。拒绝访问的错误,如果您稍后将语句与 || 组合在一起,这将成为一个问题.

要解决此问题,您可以使用:

match /{path=**}/documents/{documentId} {
allow list, get: if request.auth.uid in resource.data.access
&& resource.data.access[request.auth.uid] == true;
}

或者在找不到所需的键时提供后备值:

match /{path=**}/documents/{documentId} {
allow list, get: if resource.data.access.get(request.auth.uid, false) == true;
}

作为违反规则的示例,假设您希望“员工”用户能够阅读文档,即使他们不在该文档的 access 中 map 。

这些规则总是会出错并失败(如果工作人员的用户 ID 不在 access map 中):

match /{path=**}/documents/{documentId} {
allow list, get: if resource.data.access[request.auth.uid] == true
|| get(/databases/$(database)/documents/users/$(request.auth.uid)).data.get("staff", false) == true;
}

然而,这些规则会起作用:

match /{path=**}/documents/{documentId} {
allow list, get: if resource.data.access.get(request.auth.uid, false) == true
|| get(/databases/$(database)/documents/users/$(request.auth.uid)).data.get("staff", false) == true;
}

顺便说一句,除非您需要查询用户无权访问的文档,否则从访问映射中忽略该用户会更简单。

{
title: "A Great Story",
content: "Once upon a time ...",
access: {
alice: true,
david: true,
// ...
}
}

关于firebase - 火存储 : How to query a map of roles inside a subcollection of documents?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68060480/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com