我正在使用Firebase实时数据库。我有一个结构,以防止许多孩子。我有2把钥匙。一个用于max(max_people),另一个包含有多少个孩子(registered_people)。
我的结构:
我有max_people键。这是可以在已批准密钥中的最大子项。 Registered_people正在计算批准密钥中有多少个孩子。
这是我的安全规则:
"registrations": {
"approved": {
".write": "(root.child('/agenda/activitys').child($room_id).child('max_people').val() > root.child('/agenda/activitys').child($room_id).child('registered_people').val())"
}
我在firebase规则中做的是检查是否有很多行。如果有很多我阻止写作。这可以按预期工作。
但是现在问题是,max_people例如是20,registered_people也是20.不会发生写入。因为我已经宣布了。但是我怎么能允许删除。因为我想随时删除。
所以简而言之,我想删除无论如何。我想用现行规则写作。
更多信息:
我使用以下代码将数据添加到密钥:
let data = [
"full_name": "test",
"email_addres": "test",
]
Database.database().reference().child("agenda/activitys/" + event + "/registrations/approved").child(Auth.auth().currentUser!.uid).setValue(data) { (error, ref) in
print("got from subscribing \(String(describing: error))")
if((error) != nil){
completionHandler(Result.failure(ApiError.noMorePlaces))
return
} else {
completionHandler(Result.success("succes \(event)"))
return
}
}
按预期添加作品。
我使用以下代码删除数据:
Database.database().reference().child("agenda/activitys/" + event + "/registrations/approved").child(Auth.auth().currentUser!.uid).removeValue { (error, ref) in
if((error) != nil){
completionHandler(Result.failure(ApiError.unknownError))
return
} else {
completionHandler(Result.success("succes \(event)"))
return
}
}
删除无法按预期工作。如果最多有20个密钥,我会收到permission_denied错误。并且最大限度地被充分利用(所以我有20个密钥与批准的孩子下的数据)。
错误:
[Firebase/Database][I-RDB038012] setValue: or removeValue: at /agenda/activitys/Jumping Fitness/registrations/approved/exCnADF43AdFUzGsi0GllEsZJZY2 failed: permission_denied
但是当小于最大键数时,删除工作。
编辑: 我已经在firebase规则模拟器上测试了建议的解决方案。我也有模拟写错误。
我认为我有解决方案。我删除了密钥,所以在规则上我也需要密钥。我的解决方案:
"registrations": {
"approved": {
".write": "(root.child('/agenda/activitys').child($room_id).child('max_people').val() > root.child('/agenda/activitys').child($room_id).child('registered_people').val())",
"$key" : {
".write" : "!newData.exists()"
}
}
答案 0 :(得分:2)
删除数据时,newData
变量将为null。因此,您可以使用exists()
方法检查它是否存在:
"registrations": {
"approved": {
".write": "(root.child('/agenda/activitys').child($room_id).child('max_people').val() > root.child('/agenda/activitys').child($room_id).child('registered_people').val()) || !newData.exists()"
}
更新:查看您提供的代码后,我可以看到您对子密钥执行了写操作。但请记住,根据documentation:
较浅的安全规则会覆盖更深层路径的规则。
这意味着"批准"下的写规则将覆盖" $ key"的写规则。所以你应该加入这两个规则并将它们保存在" $ key"规则。像这样:
"registrations": {
"approved": {
"$key" : {
".write" : "(root.child('/agenda/activitys').child($room_id).child('max_people').val() > root.child('/agenda/activitys').child($room_id).child('registered_people').val()) || !newData.exists()"
}
}