Firebase会在随机setValue()子级数据上返回权限被拒绝

时间:2017-10-25 07:01:53

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

我正在测试Firebase规则,以便为Firebase数据库中的数据条目添加更多安全性。我想确保:

  1. 只有Firebase经过身份验证的“用户”才能将自己的帐户信息读/写为“帐户”

  2. 只有Firebase经过身份验证的“用户”可以将自己的角色数据读/写为“消息”。

  3. 为此,我写了以下规则:

    {
      "rules": {
        "account": {
          "$uid": {
            ".read": "auth.uid === $uid",
            ".write": "auth.uid === $uid"           
          }     
        },  
        "messages": {
            "$message_id": {
            ".read": "auth !== null",
            ".write": "auth.uid === newData.child('_uid').val() && 
                root.child('account').hasChild(auth.uid) === true"  
          },
        }
      }
    }
    

    上面的规则看起来是正确的,但是我在<3>的“messages”子节点上得到“failed:DatabaseError:Permission denied”我正在推送登录用户帐户。

    以下是我推送到firebase方法的代码段:

    public void saveToFirebase(){
      String echo = "";
      String _uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
      DatabaseReference mCurrentRecord = mFirebaseGame.push();
      Log.d(LOG, "User is " + _uid + "\nNew record ID: " + mCurrentRecord.getKey());
    
      gameCharacter.map.put("_uid", _uid);
    
      try{
        for(String keys : gameCharacter.map.keySet()){
          echo += keys + ":" + gameCharacter.map.get(keys) + "\n";
          mCurrentRecord.child(keys).setValue(gameCharacter.map.get(keys));
        }
      }
      catch(Exception e){
        error = e.toString();
      }
    }
    

    以下是我收到的权限被拒绝错误:

    Permission denied for txtStr, txtCharName and txtEner

    我无法理解为什么我只会为子节点“txtStr,txtCharName和txtEner”获取权限被拒绝错误,而其余部分已成功推送到数据库。

    我希望您能指出我的Firebase规则结构中是否遗漏了任何内容。谢谢。

1 个答案:

答案 0 :(得分:1)

这个问题的正确答案是@Frank van Puffelen指出,通过调用 mCurrentRecord.setValue(gameCharacter.map)一次插入所有子节点值,而不是迭代放置数据单独设置setValue()。

这是因为“messages”规则检查newData中的一组批量插入子节点。

"messages": {
   "$message_id": {
      ".read": "auth !== null",
      ".write": "auth.uid === newData.child('_uid').val() && 
         root.child('account').hasChild(auth.uid) === true"  
   },
}