无法为 android 应用的特定经过身份验证的用户 (uid) 编写顶级集合(列表权限)的 Firestore 安全规则
Can not write firestore security rule for top level collection (list permission) given a specific authenticated user (uid) for an android app
我刚开始使用 Firebase 服务 (firestore),但我不明白为什么以下内容不起作用。
这是我的安全规则文件:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if request.auth.uid == resource.data.user_id;
}
}
我的数据库结构如下:
名为 memos 的顶级集合包含文档。在我的示例中,我只有一个“H5i5p0zenBwkV7vsS12G”。它以其自动生成的 ID 命名。本文档有 2 个数据字段。一个“user_id”字符串数据等于“7llpal4k0xVxILawceAPPsJe3Vy1”和一个“title”字符串数据等于“Hello Firestore User”。
/memos/H5i5p0zenBwkV7vsS12G with some data: {
title: "Hello Firestore User"
user_id: "7llpal4k0xVxILawceAPPsJe3Vy1"
}
当我 运行 a get (/databases/(default)/documents/memos/H5i5p0zenBwkV7vsS12G)使用测试工具和我的 android 应用程序进行操作。
但是每次我使用
请求memos集合的列表时
Firebase.firestore.collection("memos")
它因权限被拒绝异常而失败。这是相关的日志:
2021-11-08 19:36:00.946 2996-3045/com.ygoular.memo I/Firestore: (23.0.4) [WatchStream]: (e04cf9f) Stream sending: # com.google.firestore.v1.ListenRequest@7a872c89
add_target {
query {
parent: "projects/memo-da978/databases/(default)/documents"
structured_query {
from {
collection_id: "memos"
}
order_by {
direction: ASCENDING
direction_value: 1
field {
field_path: "__name__"
}
}
}
}
target_id: 2
}
database: "projects/memo-da978/databases/(default)"
2021-11-08 19:36:00.946 2996-3045/com.ygoular.memo I/Firestore: (23.0.4) [FirestoreCallCredentials]: Successfully fetched token.
2021-11-08 19:53:05.815 4440-4480/com.ygoular.memo I/Firestore: (23.0.4) [WatchStream]: (2faa0c0) Stream received: # com.google.firestore.v1.ListenResponse@c4bcaabe
target_change {
cause {
code: 7
message: "Missing or insufficient permissions."
}
target_change_type: REMOVE
target_change_type_value: 2
target_ids: 2
}
本次调用是通过身份验证后进行的。我确定我的应用程序当时已经过身份验证,因为如果我使用以下内容修改安全规则:
allow read, write: if request.auth.uid != null
它传递和 returns 可用的备忘录。我也确定用户 ID 应该匹配,因为我粘贴了
返回的值
FirebaseAuth.getInstance().currentUser.uid
执行phone 身份验证后到数据库中的备注“user_id”字段。对于该提供商 (phone),此 ID 永远不会更改。
这里是从logcat:
获取的uid
2021-11-08 19:53:05.633 4440-4440/com.ygoular.memo E/Test: uid: 7llpal4k0xVxILawceAPPsJe3Vy1
我能做到这一点的唯一方法是创建一个顶级集合 /users,将其文档名称作为其用户 ID。在这种情况下,文档包含子集合 /memos 并且规则看起来像这样:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/users/{userId}/{anythingBehind=**} {
allow read, write: if request.auth.uid == userId;
}
}
如果您知道如何解决这个问题,请告诉我! :) 非常感谢。
规则不是过滤器
我再重复一遍
规则不是过滤器
事实上,我会让文档再重复一遍:
https://firebase.google.com/docs/firestore/security/rules-query
规则不检查每条记录以查看是否允许每条记录。规则检查查询 AS WRITTEN 可能 匹配不允许的记录 - 在这种情况下,不允许使用 ENTIRE QUERY。它甚至不检查其中一条记录是否有效——您必须执行至少指定 user_Id 字段的查询。
我刚开始使用 Firebase 服务 (firestore),但我不明白为什么以下内容不起作用。
这是我的安全规则文件:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if request.auth.uid == resource.data.user_id;
}
}
我的数据库结构如下:
名为 memos 的顶级集合包含文档。在我的示例中,我只有一个“H5i5p0zenBwkV7vsS12G”。它以其自动生成的 ID 命名。本文档有 2 个数据字段。一个“user_id”字符串数据等于“7llpal4k0xVxILawceAPPsJe3Vy1”和一个“title”字符串数据等于“Hello Firestore User”。
/memos/H5i5p0zenBwkV7vsS12G with some data: {
title: "Hello Firestore User"
user_id: "7llpal4k0xVxILawceAPPsJe3Vy1"
}
当我 运行 a get (/databases/(default)/documents/memos/H5i5p0zenBwkV7vsS12G)使用测试工具和我的 android 应用程序进行操作。
但是每次我使用
请求memos集合的列表时Firebase.firestore.collection("memos")
它因权限被拒绝异常而失败。这是相关的日志:
2021-11-08 19:36:00.946 2996-3045/com.ygoular.memo I/Firestore: (23.0.4) [WatchStream]: (e04cf9f) Stream sending: # com.google.firestore.v1.ListenRequest@7a872c89
add_target {
query {
parent: "projects/memo-da978/databases/(default)/documents"
structured_query {
from {
collection_id: "memos"
}
order_by {
direction: ASCENDING
direction_value: 1
field {
field_path: "__name__"
}
}
}
}
target_id: 2
}
database: "projects/memo-da978/databases/(default)"
2021-11-08 19:36:00.946 2996-3045/com.ygoular.memo I/Firestore: (23.0.4) [FirestoreCallCredentials]: Successfully fetched token.
2021-11-08 19:53:05.815 4440-4480/com.ygoular.memo I/Firestore: (23.0.4) [WatchStream]: (2faa0c0) Stream received: # com.google.firestore.v1.ListenResponse@c4bcaabe
target_change {
cause {
code: 7
message: "Missing or insufficient permissions."
}
target_change_type: REMOVE
target_change_type_value: 2
target_ids: 2
}
本次调用是通过身份验证后进行的。我确定我的应用程序当时已经过身份验证,因为如果我使用以下内容修改安全规则:
allow read, write: if request.auth.uid != null
它传递和 returns 可用的备忘录。我也确定用户 ID 应该匹配,因为我粘贴了
返回的值FirebaseAuth.getInstance().currentUser.uid
执行phone 身份验证后到数据库中的备注“user_id”字段。对于该提供商 (phone),此 ID 永远不会更改。
这里是从logcat:
获取的uid2021-11-08 19:53:05.633 4440-4440/com.ygoular.memo E/Test: uid: 7llpal4k0xVxILawceAPPsJe3Vy1
我能做到这一点的唯一方法是创建一个顶级集合 /users,将其文档名称作为其用户 ID。在这种情况下,文档包含子集合 /memos 并且规则看起来像这样:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents/users/{userId}/{anythingBehind=**} {
allow read, write: if request.auth.uid == userId;
}
}
如果您知道如何解决这个问题,请告诉我! :) 非常感谢。
规则不是过滤器
我再重复一遍
规则不是过滤器
事实上,我会让文档再重复一遍:
https://firebase.google.com/docs/firestore/security/rules-query
规则不检查每条记录以查看是否允许每条记录。规则检查查询 AS WRITTEN 可能 匹配不允许的记录 - 在这种情况下,不允许使用 ENTIRE QUERY。它甚至不检查其中一条记录是否有效——您必须执行至少指定 user_Id 字段的查询。