Firebase实时数据库的权限被拒绝

时间:2020-08-05 16:10:41

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

我有这样设置的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

已认证的用户向用户节点下的$ user_id节点发出请求时,将导致权限被拒绝错误。 Firebase数据库规则是原子性的,但是所有读取权限都在检查他是否是经过身份验证的用户或该用户是否正在访问自己的数据。当用户读取自己的数据并且满足所有读取条件,但仍然出现权限被拒绝错误时。

但是当我尝试单独阅读这些字段中的任何一个时,都没有错误

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

感谢您的帮助。 预先感谢。

1 个答案:

答案 0 :(得分: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"
          } 
...