Java Firebase规则-允许写入实时数据库中的特定路径

Java Firebase规则-允许写入实时数据库中的特定路径,java,android,firebase,firebase-realtime-database,firebase-security,Java,Android,Firebase,Firebase Realtime Database,Firebase Security,我依靠实时数据库从以下结构获取我的应用程序数据: 每个A有3个B 根据这些规则,阅读可以很好地发挥作用: { "rules": { ".read": true, ".write": false } } 现在,我处于测试模式&我想实现两件事: 1。允许用户以独占方式将写入每个A中的路径/../B3/ 2。用户在/../B3/中输入的值必须是数字(最好是整数) 因此,我做了一些研究,提出

我依靠实时数据库从以下结构获取我的应用程序数据:

每个
A
有3个
B

根据这些规则,阅读可以很好地发挥作用:

{
    "rules": {
        ".read": true,
        ".write": false
    }
}

现在,我处于测试模式&我想实现两件事:

1。允许用户以独占方式将写入每个
A
中的路径
/../B3/

2。用户在
/../B3/
中输入的值必须是数字(最好是整数)

因此,我做了一些研究,提出了一套规则:

{

  "rules": {
    "A1":{
          "B1":{
            ".read": true,
            ".write": false
           },
          "B2":{
            ".read": true,
            ".write": false
           },
        "B3":{
          ".read": true,
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A2":{
          "B1":{
            ".read": true,
            ".write": false
           },
          "B2":{
            ".read": true,
            ".write": false
           },
        "B3":{
          ".read": true,
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A3":{
          "B1":{
            ".read": true,
            ".write": false
           },
          "B2":{
            ".read": true,
            ".write": false
           },
        "B3":{
          ".read": true,
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   }
}

问题:

{

  "rules": {
".read": true, //The difference
    "A1":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A2":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A3":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   }
}
我在Firebase控制台上使用操场模拟器测试了这些规则,得到了正确的结果。但当我尝试在测试设备上读写
/../B3/
时,它不起作用。相反,我在LogCat中得到了这个异常:

com.google.firebase.database.DatabaseException: Firebase Database error: Permission denied
    at com.google.firebase.database.DatabaseError.toException(com.google.firebase:firebase-database@@16.0.4:229)
    at com.app.activity$3.onCancelled(activity.java:567)

我想我在构建规则方面遗漏了一些东西。提前感谢。

据我所知,规则的结构需要如下所示

{

  "rules": {
    "A1":{
          "B1":{
            ".read": true,
            ".write": false
           },
          "B2":{
            ".read": true,
            ".write": true //changed
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0" //added
           },
        "B3":{
          ".read": true,
          ".write": false, //changed
         }
   }
.
. //rest of the rules in the same pattern
.
由于您希望用户以独占方式将写入每个
A
子树中的
/../B2
节点,因此应仅允许用户访问每个
A
子树中的
/../B2
节点

另外,.validate规则在
/../B3
上不需要,根据

.validate
在.write规则授予访问权限后使用,以确保正在写入的数据符合特定架构

最后,需要在
/../B2
上存在.validate语句,以检查数字是否为整数

至于例外情况,很明显出现了
权限被拒绝
错误,因为
/../B2
中的.write已设置为
false

另外,还有一个旁注,设置
“.write”:true
不仅允许用户写入数据库,还允许任何人写入数据库,正如前面所指出的那样

在开发过程中,您可以使用公共规则代替默认规则来设置文件的公共可读写性。这对于原型设计非常有用,因为您可以在不设置身份验证的情况下开始。这种访问级别意味着任何人都可以读取或写入您的数据库。您应该在启动应用程序之前配置更安全的规则

因此,如果安全性是一个很小的问题,请查看规则以确保您已经实施了强制执行安全性的措施


最后,希望这能回答你的问题

我终于解决了这个问题!呸

解决方案:

{

  "rules": {
".read": true, //The difference
    "A1":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A2":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A3":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   }
}
说明:

{

  "rules": {
".read": true, //The difference
    "A1":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A2":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   },
    "A3":{
        "B3":{
          ".write": true,
            ".validate": "newData.isNumber() && newData.val() % 1 === 0.0"
         }
   }
}
我丢失了从根节点读取的权限,根据级联原则,如果无法访问子节点的父节点,则无法访问子节点(即使使用
“.read”:true
,针对每个子节点)。(合乎逻辑!)


我找到它的地方:一段43分钟的视频:p

对不起,这也不行。很抱歉误导您,我的意思是B3而不是B2,我将编辑我的问题。如果是这种情况,那么写入
/../B3
一定是由于错误的数据类型而失败,如果数据类型是数字的话?是的,它是数字的,我在您回答后尝试过,但它不起作用:(@kh3e在第一次访问RTDB之前,请尝试启用,并重复您之前采取的步骤,然后查看日志输出的内容。非常感谢,问题很简单。我发布了答案:)