Firebase实时数据库规则

huangapple go评论54阅读模式
英文:

Firebase real-time database rules

问题

以下是翻译好的部分:

这是我的示例数据库:

{
  "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"
      }
    }
  }
}

这是我在控制台中尝试设置的数据库规则:

{
  "rules": {
    "users": {
      "$user_id": {
        ".read": "$user_id == auth.uid && auth != null", 
        ".write": false 
      }
    },
      
    "withdraw_details": {
      "$user_id": {
        ".read": "$user_id == auth.uid && auth != null",
        ".write": false 
      }
    },
        
    "referrals": {
      "$user_id": {
        ".read": "$user_id == auth.uid && auth != null", 
        ".write": "$user_id == auth.uid && auth != null",
        "$date": {
          ".validate": "newData.hasChildren(['name', 'number', 'city', 'remarks'])",
          "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"},
          "$other": {".validate": false}
        }
      }
    }  
  }
}

此外,进一步澄清,我希望/users/uid/ 和 /withdraw_details/uid/ 只能由其所有者进行读取,auth 不应为 null。对于这些位置的写访问应该被拒绝。

/referrals/uid/ 位置应该对其所有者具有读和写访问权限,并且应满足上述数据库规则中的某些标准和验证要求。

英文:

Here is my example database:

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

And here are my database rules that I've tried to set in console:

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

答案1

得分: 0

安全规则本身不会过滤数据。相反,它们只是强制执行允许对数据库执行的任何操作。

因此,在您的代码中,您会将侦听器附加到 /users

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

当您这样做时,规则引擎会检查该用户是否具有对 /users 的读取权限。由于没有人对 /users 具有读取权限,它会拒绝该操作。


相反,您希望为特定用户读取节点:

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()
        );
    } 
    ...

有关更多信息,请参阅 Firebase 文档中的规则不是过滤器,关于此主题的搜索结果,以及例如:使用安全规则限制子节点/字段访问权限

英文:

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:

databaseReference.child(&quot;users&quot;).addListenerForSingleValueEvent(new ValueEventListener() {

When you do this, the rules engine checks if this user has read permission on /users. And since nobody has read permission on /users it rejects the operation.


What you'll want to do instead is read the node for the specific user:

databaseReference.child(&quot;users&quot;).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

huangapple
  • 本文由 发表于 2020年10月17日 21:02:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/64402768.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定