Permission denied for Firebase Realtime Database

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

Permission denied for Firebase Realtime Database

问题

以下是您要翻译的内容:

我已经设置了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 节点时,会导致 "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

任何帮助都将不胜感激。提前致谢。

英文:

I have firebase database rules set up like this

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

       }

The code that makes the request

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);

            }
            
});                    
  

Logged Results

I/DetailsActivity: User id KfiIFOEGWQZIc5UREqX8qo4Nmkn1
I/DetailsActivity: error DatabaseError: Permission denied

When an authenticated user is making a request to the $user_id node under users node, it results in Permission Denied error. Firebase database rules works atomically, but all the read permissions are checking whether he is an authenticated user or the user is accessing his own data. When the user reads his own data and all read conditions are satisfied but still getting Permission Denied error.

But when I try to read any of these fields individually there is no errors

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 get the log as

I/DetailsActivity: Name elsonjose

Any help is appreciated.
Thanks in advance.

答案1

得分: 1

假设您已经有一个默认设置为:

  "rules": {
    ".read": false,
    ".write": false,

您对单个字段设置了规则,但当尝试读取整个用户记录时,可能会收到“权限被拒绝”的消息,因为您没有为"$user_id"路径本身设置任何规则。尝试添加:

    "Users": {
          "$user_id": {
            // 仅允许经过身份验证的内容所有者访问其数据
            ".read": "auth != null && auth.uid == $user_id",
            ".write": "auth != null && auth.uid == $user_id"
          } 
...
英文:

Assuming that you have a default set to:

  "rules": {
    ".read": false,
    ".write": false,

You do have rules for single fields, but you are likely getting "Permission denied" when reading the whole user record because you don't have any rules set for the "$user_id" path itself. Try adding:

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

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

发表评论

匿名网友

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

确定