Firebase 实时数据库的权限被拒绝
Posted
技术标签:
【中文标题】Firebase 实时数据库的权限被拒绝【英文标题】:Permission denied for Firebase Realtime Database 【发布时间】:2020-11-25 20:51:26 【问题描述】:我有这样设置的 firebase 数据库规则
"Users":
"$user_id":
"Name":
".read":"auth != null",
".write":"auth.uid == $user_id"
,
"Email":
".read":"auth != null",
".write":"auth.uid == $user_id"
,
"Address":
".read":"auth != null",
".write":"auth.uid == $user_id"
,
"Photo":
".read":"auth != null",
".write":"auth.uid == $user_id"
,
"Number":
".read":"auth.uid == $user_id",
".write":"auth.uid == $user_id"
,
"Current":
".read":"auth != null",
".write":"auth.uid == $user_id"
发出请求的代码
FirebaseAuth mAuth = FirebaseAuth.getInstance();
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference().child(FirebaseConstants.USERS).child(mAuth.getCurrentUser().getUid());
if(mAuth.getCurrentUser() !=null)
Log.i("DetailsActivity","User id "+mAuth.getCurrentUser().getUid());
else
Log.i("DetailsActivity","User not authenticated");
userRef.addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
if(dataSnapshot.hasChild(FirebaseConstants.NAME))
Name = dataSnapshot.child(FirebaseConstants.NAME).getValue().toString();
UserNameEdittext.append(Name);
if(dataSnapshot.hasChild(FirebaseConstants.EMAIL))
Email = dataSnapshot.child(FirebaseConstants.EMAIL).getValue().toString();
UserEmailEdittext.append(Email);
userInfoProgressbar.setVisibility(View.INVISIBLE);
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
userInfoProgressbar.setVisibility(View.INVISIBLE);
Log.i("DetailsActivity","error "+databaseError);
);
记录结果
I/DetailsActivity: User id KfiIFOEGWQZIc5UREqX8qo4Nmkn1
I/DetailsActivity: error DatabaseError: Permission denied
认证用户向users节点下的$user_id节点发出请求时,会导致Permission Denied错误。 Firebase 数据库规则以原子方式工作,但所有读取权限都在检查他是经过身份验证的用户还是用户正在访问他自己的数据。当用户读取自己的数据并且所有读取条件都满足但仍然出现Permission Denied错误。
但是当我尝试单独读取这些字段中的任何一个时,都没有错误
userRef.child(FirebaseConstants.NAME).addListenerForSingleValueEvent(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
if(dataSnapshot.exists())
Name = dataSnapshot.getValue().toString();
Log.i("DetailsActivity","Name "+Name);
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
userInfoProgressbar.setVisibility(View.INVISIBLE);
Log.i("DetailsActivity","error "+databaseError);
);
我得到的日志是
I/DetailsActivity: Name elsonjose
感谢任何帮助。 提前致谢。
【问题讨论】:
请编辑问题以显示执行查询的代码。还要在该示例中说明您确定用户在查询时已登录。 试试这些:***.com/questions/40942493/…。 ***.com/questions/37424544/… @Sadegh 尝试刷新 google-services.json,没有运气。 【参考方案1】:假设您有一个默认设置为:
"rules":
".read": false,
".write": false,
您确实有针对单个字段的规则,但是在读取整个用户记录时您可能会收到“权限被拒绝”,因为您没有为 "$user_id"
路径本身设置任何规则。尝试添加:
"Users":
"$user_id":
// Allow only authenticated content owners access to their data
".read": "auth != null && auth.uid == $user_id",
".write": "auth != null && auth.uid == $user_id"
...
【讨论】:
是的,这行得通,但我想允许某些用户仅访问特定数据。在浏览了文档后,我发现我们不能真正使用 firebase 规则来过滤用户。对于过滤用户,我发现一些有用的链接是 [toptal.com/firebase/role-based-firebase-authentication] [medium.com/firebase-tips-tricks/… 如果您想拥有用户角色和围绕它们的规则,您可以在存储用户属性的数据库中创建一个“配置文件”集合。这是我所知道的仅使用 firebase 工具实现功能的唯一方法。以上是关于Firebase 实时数据库的权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章
Firebase实时数据库:DatabaseError权限被拒绝