简体   繁体   English

Firebase 实时数据库规则

[英]Firebase real-time database rules

Here is my example database:这是我的示例数据库:

{
  "referrals" : {
    "Nr7sS4xV1fO59wjCqbEabLlK8RF3" : {
      "16-10-2020" : {
        "-MJhjQddWdWDImj98Sov" : {
          "city" : "hyhy",
          "name" : "mmmm",
          "number" : "03058852844",
          "remarks" : "pg"
        },
        "-MJhmeRiqeXskncHJF61" : {
          "city" : "vsva",
          "name" : "yhyh",
          "number" : "02089453882",
          "remarks" : "pg"
        }
      },
      "total_referrals" : 2
    },
    "jpeoZQAPdZY4yEt8yGifGZi4U4r1" : {
      "16-10-2020" : {
        "-MJlzrS8xX8MGN1ar9uw" : {
          "city" : "lahore",
          "name" : "khursand",
          "number" : "03014181394",
          "remarks" : "paid"
        },
        "-MJm-LFhEEMBzBPRftlC" : {
          "city" : "lahore",
          "name" : "khursand",
          "number" : "03014141111",
          "remarks" : "pg"
        }
      },
      "total_referrals" : 2
    }
  },
  "users" : {
    "Nr7sS4xV1fO59wjCqbEabLlK8RF3" : {
      "account_status" : "Level 1",
      "current_balance" : "0",
      "isBan" : false,
      "paid_referrals" : "0",
      "total_balance" : "0",
      "total_withdraw" : "0"
    },
    "jpeoZQAPdZY4yEt8yGifGZi4U4r1" : {
      "account_status" : "Level 1",
      "current_balance" : "0",
      "paid_referrals" : "0",
      "total_balance" : "0",
      "total_withdraw" : "0"
    }
  },
  "withdraw_details" : {
    "Nr7sS4xV1fO59wjCqbEabLlK8RF3" : {
      "-MJMgVd3TuWYjdGSd-FY" : {
        "amount" : "600",
        "date" : "11/10/2020",
        "method" : "Easypaisa",
        "number" : "03058853833",
        "tid" : "90124678573"
      }
    },
    "jpeoZQAPdZY4yEt8yGifGZi4U4r1" : {
      "-MJm7SfTwWafae85ayRq" : {
        "amount" : "600",
        "date" : "11/10/2020",
        "method" : "Easypaisa",
        "number" : "03494628929",
        "tid" : "90124678573"
      }
    }
  }
}

And here are my database rules that I've tried to set in console:这是我尝试在控制台中设置的数据库规则:

{
  "rules": {
    "users":{
      "$user_id":{
        ".read": "$user_id == auth.uid && auth != null", // only owner or authenticated user can read
        ".write": false // No-one can write
          
      }
    },
      
    "withdraw_details":{
      "$user_id":{
        ".read": "$user_id == auth.uid && auth != null",// only owner or authenticated user can read
        ".write": false // No-one can write
      }
    },
        
    "referrals": {
      "$user_id": {
        ".read": "$user_id == auth.uid && auth != null", // same as above
        ".write": "$user_id == auth.uid && auth != null", // owner and authenticated can write
          "$date": {
            // children should be only these
            ".validate": "newData.hasChildren(['name', 'number', 'city', 'remarks'])",
              // you can see further validation rules below
            "name": {".validate": "newData.isString() && newData.val().length <= 30"},
            "number": {".validate": "newData.isNumber() && newData.val().length == 11"},
            "city": {".validate": "newData.isString() && newData.val().length <= 20"},
            "remarks": {".validate": "newData.isString() && newData.val().length <= 15"},
            
              // any other child should be rejected
            "$other": {".validate": false}
            
          }
      }
    }  
  }

Now I don't know what I am doing wrong here because every time I try to read any child it throws a "Permission denied" error.现在我不知道我在这里做错了什么,因为每次我尝试读取任何孩子时都会抛出“权限被拒绝”错误。

Like a user details request below喜欢下面的用户详细信息请求

private void getDetails() {
    databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {

            if (snapshot.hasChild(mAuth.getCurrentUser().getUid())) {

                AccountDetails accountDetails = snapshot
                        .child(mAuth.getCurrentUser().getUid())
                        .getValue(AccountDetails.class);

                setValuesToTextViews(
                        accountDetails.getTotal_balance(),
                        accountDetails.getTotal_withdraw(),
                        accountDetails.getCurrent_balance(),
                        accountDetails.getAccount_status(),
                        accountDetails.getPaid_referrals(),
                        accountDetails.getTotal_referrals()
                );
            } 
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.w(TAG, "onCancelled: " + error.toException());

            Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

Moreover, on further clarification, I want the /users/uid/ && /withdraw_details/uid/ to be read only by it's owner and auth shouldn't be null.此外,进一步澄清,我希望 /users/uid/ && /withdraw_details/uid/ 只能由其所有者读取,并且 auth 不应为空。 and write access to these locations should be denied.并且应该拒绝对这些位置的写访问。

The /referrals/uid/ location should have read and write access to its owner and with certain criteria and validations as you can see in the database rules above. /referrals/uid/ 位置应该对其所有者具有读写访问权限,并具有某些标准和验证,如您在上面的数据库规则中所见。

Security rules on their own don't filter data.安全规则本身不会过滤数据。 Instead they merely enforce that any operation you perform on the database is allowed.相反,它们只是强制允许您对数据库执行的任何操作。

So in your code, you attach a listener to /users :因此,在您的代码中,您将一个侦听器附加到/users

databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() {

When you do this, the rules engine checks if this user has read permission on /users .执行此操作时,规则引擎会检查此用户是否对/users具有读取权限。 And since nobody has read permission on /users it rejects the operation.并且由于没有人对/users具有读取权限,因此它拒绝该操作。


What you'll want to do instead is read the node for the specific user:您要做的是读取特定用户的节点:

databaseReference.child("users").child(mAuth.getCurrentUser().getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        AccountDetails accountDetails = snapshot.getValue(AccountDetails.class);

        setValuesToTextViews(
                accountDetails.getTotal_balance(),
                accountDetails.getTotal_withdraw(),
                accountDetails.getCurrent_balance(),
                accountDetails.getAccount_status(),
                accountDetails.getPaid_referrals(),
                accountDetails.getTotal_referrals()
        );
    } 
    ...

For more on this, see the Firebase documentation on rules are not filters , these search results about the topic and for example: Restricting child/field access with security rules有关更多信息,请参阅有关规则不是过滤器的 Firebase 文档、有关该主题的这些搜索结果,例如:使用安全规则限制子/字段访问

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM