Firebase 实时数据库规则
Posted
技术标签:
【中文标题】Firebase 实时数据库规则【英文标题】:Firebase real-time database rules 【发布时间】:2021-01-31 18:42:05 【问题描述】:这是我的示例数据库:
"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", // 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
现在我不知道我在这里做错了什么,因为每次我尝试读取任何孩子时都会引发 “Permission denied” 错误。
喜欢下面的用户详细信息请求
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();
);
此外,进一步澄清,我希望 /users/uid/ && /withdraw_details/uid/ 只能由其所有者读取,并且 auth 不应为空。并且应该拒绝对这些位置的写访问。
/referrals/uid/ 位置应该对其所有者具有读写权限,并具有某些标准和验证,如您在上面的数据库规则中所见。
【问题讨论】:
【参考方案1】:安全规则本身不会过滤数据。相反,它们只是强制您对数据库执行的任何操作都是允许的。
因此,在您的代码中,您将侦听器附加到 /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()
);
...
有关这方面的更多信息,请参阅 rules are not filters 上的 Firebase 文档,这些 search results 关于该主题,例如:Restricting child/field access with security rules
【讨论】:
为什么这个写操作失败了?databaseReference.child("referrals").child(mAuth.getCurrentUser().getUid()).child(utils.getDate(getActivity())).push().setValue(details);
如果没有看到您如何填充 details
,这很难说。我建议使用新的MCVE 发布一个新问题。以上是关于Firebase 实时数据库规则的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 实时规则如何检查具有 AutoID 的节点是不是包含正确的数据