我对实时数据库安全规则有疑问。
我的数据是这样构造的:
-房间
每个节点都是根据参与该房间的用户 ID 生成的。
但是,当我尝试设定规则时,例如:
"chats": {
"$room_x":{
"$room_y":{
"$room_ID":{".write": "auth != null",
".read": "auth != null", } }} }
即使我设置 '".read" = true',每个请求都会被拒绝,并显示“PERMISSION_DENIED:缺少或不足的权限”,就好像我无法查询正确的数据库注释一样。
但是,如果我将规则设置为
"chats": {
"$roomX":{
"$roomY":{
".write": "auth != null",
".read": "auth != null",
}}},
效果很好。
我的flutter客户端请求是
rtdb
.child(chats)
.child(X)
.child(Y)
.child(roomID)
.orderByChild('ts')
.onValue
.listen((event) {}
如果我尝试打印子密钥和路径 - 两者似乎都是正确的:
print(event.snapshot.key) -> I/flutter ( 7356): X_Y
print(event.snapshot.ref.path); -> I/flutter ( 7356): chats/X/Y/X_Y
对我来说,将规则设置为“roomY”下一个节点非常重要,因为这将允许我检查 $room_ID 是否包含正确的用户 ID,例如:
"chats": {
"$roomX":{
"$roomY":{
"$roomID":{
".write": "auth != null && $roomID.contains(auth.uid)",
".read": "auth != null && $roomID.contains(auth.uid)",
},
此代码适用于 Playground,但不适用于 Flutter 查询。我在这里缺少什么?
我只是尝试重现,但一切都按我的预期进行。
我的设置如下。
代码:
await FirebaseAuth.instance.signInAnonymously();
final db = FirebaseDatabase.instance.ref('78358207');
final uid = FirebaseAuth.instance.currentUser!.uid;
print(uid);
final roomID = uid+"_"+"otheruid";
final roomRef = db.child(roomID);
roomRef.onValue.listen((event) {
print("Room ${roomID} has value ${event.snapshot.value}");
});
roomRef.set(DateTime.now().millisecondsSinceEpoch);
规则:
{
"rules": {
"78358207": {
"$roomID":{
".write": "auth != null && $roomID.contains(auth.uid)",
".read": "auth != null && $roomID.contains(auth.uid)",
}
},
...
路径中的
78358207
是您的问题 ID,所以没什么神奇的。除此之外,所有值都在代码本身中。每次执行此代码时,写入操作都会成功,并且值侦听器会打印该值。
您可以在此处执行此重现:https://zapp.run/edit/rtdb-access-key-containing-uid-zl4e06oil4f0