允许删除并使用Firebase规则进行写入

问题描述 投票:0回答:1

我正在使用Firebase实时数据库。我有一个结构,以防止许多孩子。我有2把钥匙。一个用于max(max_people),另一个包含有多少个孩子(registered_people)。

我的结构:

enter image description here

我有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()"
        }
  }
firebase firebase-realtime-database firebase-security-rules
1个回答
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()"
        }
  }
© www.soinside.com 2019 - 2024. All rights reserved.