我遇到的问题是,通过下面显示的以下firebase规则,经过身份验证的用户可以成功写入数据库但无法从中读取,因为我在控制台中获得了“权限被拒绝”。当我将读取和写入都设置为true(public)时,读取和写入功能都正常工作。我从数据库中读取的代码也如下所示:
private String userID;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//Authenticate user
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
FirebaseUser user = mAuth.getCurrentUser();
if(mAuth.getCurrentUser() == null){
finish();
startActivity(new Intent(this, MainActivity.class));
}
userID = user.getUid();
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<CharSequence> array = new ArrayList<>(Arrays.asList(HomeActivity.this.getResources().getTextArray(R.array.array)));
map = (Map<String, Object>) dataSnapshot.child("users").child(userID).getValue();
int x = 16;
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
array.add(x, key);
x++;
}
规则:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
示例数据库:
{
"users" : {
"9kV3otdvOXU0ssMZWIdfggrBrj63" : {
"Citrus" : [ "orange", "lime", "mandarin", "lemon" ],
"Fruit" : [ "apple", "banana", "mango" ],
"Meat" : [ "beef", "pork", "lamb", "chicken" ],
"Veg" : [ "tomato", "potato", "cabbage" ]
}
}
}
这是确切的错误:
W/SyncTree: Listen at / failed: DatabaseError: Permission denied
正如道格已经评论过的那样,如果没有看到你附加听众的数据就很难帮助(所以你称之为DatabaseReference
或addValueListener
的addListenerForSingleValueEvent
)。但是从听众的这段代码来看,你似乎在听/
。
dataSnapshot.child("users")
您的用户均无权阅读/
,因为您只允许他们访问/users/$uid
。您的代码现在不仅违反了您的安全规则,如果它有效,它将下载的数据超出了所需的数量。
相反,您应该将侦听器附加到JSON树中的最低级别,该级别包含您需要的所有数据(并具有读取权限)。在您的情况下,似乎是/users/$uid
,所以你做:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
DatabaseReference userRef = usersRef.child(userID);
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<CharSequence> array = new ArrayList<>(Arrays.asList(HomeActivity.this.getResources().getTextArray(R.array.array)));
map = (Map<String, Object>) dataSnapshot.getValue();
int x = 16;
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
array.add(x, key);
x++;
}