英文:
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"
}
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论