【问题标题】:Allow delete and write with Firebase Rules允许使用 Firebase 规则进行删除和写入
【发布时间】:2018-03-04 14:14:13
【问题描述】:

我正在使用 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()"
        }
  }

【问题讨论】:

    标签: firebase firebase-realtime-database firebase-security


    【解决方案1】:

    删除数据时,newData 变量将为空。所以你可以使用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

    较浅的安全规则会覆盖较深路径的规则。

    这意味着“approved”下的写规则将覆盖“$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()"
            }
      }
    

    【讨论】:

    • 我已经尝试过了。我收到 permission_denied 错误。我在批准的密钥上删除它。按预期添加作品。
    • 请显示您正在使用的代码,该代码授予您权限_拒绝
    • 当里面有 20 个值时,什么都不能按预期添加。没有任何值可以被删除。但只要值少于 20 个,删除就会按预期工作。我很快就会发送代码。
    • 检查!newData.exists() 是测试空写的方法。如果它对您不起作用,那取决于您正在编写的内容和当前数据。请更新您的问题,以显示重现您所询问情况的确切数据和代码。
    • @RosárioPereiraFernandes 我添加了更多代码和示例。
    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 2018-01-05
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2020-03-22
    相关资源
    最近更新 更多