Firestore安全规则:在文档中的数组中搜索用户的id。

5 浏览
0 Comments

Firestore安全规则:在文档中的数组中搜索用户的id。

首先,对于我的糟糕英语表示抱歉,这不是我的母语...

我正在使用Firestore数据库在Firebase中构建一个简单的应用程序。在我的应用中,用户是小组的成员。他们可以访问其他用户的数据。

为了不查询太多文档(每个用户一个文档,在小组文档的子集合中),我选择将用户的数据添加到小组文档内的数组中。

这是我的小组文档:

{

"name":"fefefefe",

"days":[false,false,false,false,true],

"members":[

{"email":"eee@ff.com","id":"aaaaaaaa","name":"Mavireck"},

{"email":"eee2@ff.com","id":"bbbbbbbb","name":"Mavireck2"},

],

}

如何在安全规则中检查用户是否在一个小组中?

我应该使用对象吗?

我真的不想使用用户的子集合,因为我很快就会达到免费配额的限制...

谢谢您花时间阅读!

编辑:

感谢您的答复。我将把它更改为对象:

"Members": { uid1 : {}, uid2 : {} }

0
0 Comments

Firestore安全规则:在文档中搜索用户的id的数组的出现原因和解决方法

问题的出现原因:

该问题的出现是因为需要在Firestore的安全规则中,允许某个用户读取/写入集合中的某个文档,前提是该用户存在于另一个集合的数组中。

解决方法:

为了解决这个问题,可以使用以下代码来实现:

service cloud.firestore {

match /databases/{database}/documents {

match /repositories/{accountId} {

allow read, write: if request.auth.uid in get(/databases/$(database)/documents/accounts/$(accountId)).data.users

}

}

}

这段代码中,使用了get()函数来获取另一个集合中的文档,然后通过判断当前用户的uid是否存在于该文档中的users数组中,来决定是否允许读取/写入操作。

然而,需要注意的是,使用get()函数会导致额外的读取操作,即使规则拒绝了请求,也会计入费用。所以需要注意这一点。

另外,有其他用户提供了一种不需要额外读取操作的解决方法,但是该方法只适用于访问特定资源的情况,而上述解决方法适用于任何资源的访问。

通过以上解决方法,我们可以在Firestore的安全规则中实现对某个用户id在文档的数组中进行搜索的功能。这样可以实现只允许特定用户访问特定资源的需求。同时,需要注意使用get()函数可能会产生额外的读取操作。

0
0 Comments

Firestore安全规则:在文档中的数组中搜索用户ID的问题的出现的原因是为了在查询集合和排序时避免使用基于用户ID的复合索引,以及为了在UI中呈现信息或进行其他类型的处理时使用附加字段。解决方法是将用户ID存储在两个单独的字段中,一个用于集合查询和Firestore规则,另一个用于UI呈现和其他处理。这样做可以避免使用复合索引,并提供了一种解决方案,但也有其自身的优缺点。

0
0 Comments

问题出现的原因:

用户想要在Firestore的安全规则中搜索一个文档中数组中的用户ID,但尝试了多种方法却无法实现。

解决方法:

1. 使用resource.data.members[request.auth.uid] != null来检查数组中是否存在用户ID。

2. 使用子集合来实现权限控制,通过在子集合中检查用户ID是否存在来控制用户对文档的读取权限。

3. 在实际应用中测试代码,因为模拟器对于数组操作有一些问题。

4. 针对集合查询,需要将解决方法与适当的查询绑定起来。

下面整理成一篇文章:

Firestore安全规则:在文档的数组中搜索用户ID的方法

在Firestore中,有时我们希望根据用户ID来控制对文档的读取权限。下面是一些解决这个问题的方法。

方法一:使用数组中的用户ID来控制权限

一般情况下,我们可以编写如下规则来实现:

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection/{documentId} {
      // 如果 `members` = [uid1, uid2, uid3],则允许读取
      // 无法遍历集合并检查成员
      allow read: if request.auth.uid in resource.data.members;
      // 也可以使用 `members` = {uid1: {}, uid2: {}} 的形式
      allow read: if resource.data.members[request.auth.uid] != null;
    }
  }
}

方法二:使用子集合来控制权限

如果你想根据用户是否在房间中来控制对消息的读取权限,可以使用子集合来实现:

service cloud.firestore {
  match /databases/{database}/documents {
    // 如果用户在房间中,则允许读取消息
    match /rooms/{roomId} {
      match /documents/{documentId} {
        allow read: if exists(/databases/$(database)/documents/documents/$(documentId)/users/$(request.auth.uid));
      }
      match /users/{userId} {
        // 允许用户操作文档的规则
      }
    }
  }
}

问题解决方案:

用户反馈了一些问题,以下是针对这些问题的解决方法:

- 当使用resource.data.members[request.auth.uid] != null;时,无法实现预期的结果。可以尝试使用resource.data.members[request.auth.uid].name != null;resource.data.members[(request.auth.uid)] != null;来进行判断。

- 进行了本地测试,if(doc.data()['members'][(firebase.auth()currentUser.uid)] != null){console.log("not null)}始终输出"not null"。

- 需要注意的是,allow read: if resource.data.membres[(request.auth.uid)] != null;无法实现预期的结果,而allow read: if resource.data.membres != null;可以实现。

- 如果你只在提供的模拟器中进行测试,建议在实际应用中进行测试,因为模拟器在处理数组时存在一些问题。

通过Firestore的安全规则,我们可以根据用户ID来控制对文档的读取权限。可以使用数组中的用户ID来进行权限控制,也可以通过子集合来实现。在实际应用中,需要注意模拟器对数组操作的问题,并将解决方法与适当的查询绑定起来,以实现集合查询的权限控制。

0