java - 无法从 Firebase 读取数据 - Firebase DatabaseError:权限被拒绝
问题描述
我创建了一个简单的应用程序,用户可以在该应用程序上注册登录。身份验证工作正常。我还添加了一个实时数据库。当我尝试从 firebase 读取数据时,我得到“权限被拒绝”,尽管“写入数据”工作正常。我想获取登录用户的数据。这是firebase规则:
{
"rules": {
"users": {
"$userId": {
".write": "$userId === auth.uid",
".read": "$userId === auth.uid"
}
}
}
}
这是写方法(这很完美):
public void writeUserInfo(){
String username = etUserName.getText().toString().trim();
String age = etAge.getText().toString().trim();
String sex = etSex.getText().toString().trim();
if(username.isEmpty()){
etUserName.setError("user name required");
etUserName.requestFocus();
return;
}
if(age.isEmpty()){
etAge.setError("age required");
etAge.requestFocus();
return;
}
if(sex.isEmpty()){
etSex.setError("sex required");
etSex.requestFocus();
return;
}
User user = new User(username,age,sex);
mDatabase.child("users/"+firebaseUser.getUid()).setValue(user);
}
这是读取方法:
public void readUserData(){
mDatabase.child("users").orderByChild(userId).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
//array list to staore user data as elements
ArrayList<User> userData = new ArrayList<>();
for(DataSnapshot snapshot:dataSnapshot.getChildren()){
User element = snapshot.getValue(User.class);
userData.add(element);
}
for(User user: userData){
etUserName.setText(user.getmUsername());
etAge.setText(user.getmAge());
etSex.setText(user.getmSex());
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
这是数据库层次结构: Firebase 控制台 我还包括登录和注册方法:
登录方式:
public void signIn(){
String userEmail = etEmail.getText().toString().trim();
String userPassword = etPassword.getText().toString().trim();
//validation
//validation
if(userEmail.isEmpty()){
etEmail.setError("Email is required");
//et is focused
etEmail.requestFocus();
return;
}
if(!Patterns.EMAIL_ADDRESS.matcher(userEmail).matches()){
etEmail.setError("Invalid email address");
//focus et
etEmail.requestFocus();
return;
}
if(userPassword.isEmpty()){
etPassword.setError("Password is required");
//et is focused
etPassword.requestFocus();
return;
}
if(userPassword.length()<6){
etPassword.setError("Password length should be atleast 6 characters");
//request focus
etPassword.requestFocus();
return;
}
//setting progress bar
progressBar.setVisibility(View.VISIBLE);
//firebase signin method
mAuth.signInWithEmailAndPassword(userEmail,userPassword).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
//hiding progress bar
progressBar.setVisibility(View.GONE);
if(task.isSuccessful()){
Intent intent = new Intent(getApplicationContext(),Profile.class);
//this flag will clear all the open activities
//so that user cant go back to login activyty upon pressing
//back button
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
Toast.makeText(getApplicationContext(),"Logged in successfully",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),task.getException().getMessage(),Toast.LENGTH_SHORT).show();
}
}
});
}
这是signUp方法:
public void userRegistration(){
String userEmail = etSignupEmail.getText().toString().trim();
String userPassword = etSignupPassword.getText().toString().trim();
//validation
if(userEmail.isEmpty()){
etSignupEmail.setError("Email is required");
//et is focused
etSignupEmail.requestFocus();
return;
}
if(!Patterns.EMAIL_ADDRESS.matcher(userEmail).matches()){
etSignupEmail.setError("Invalid email address");
//focus et
etSignupEmail.requestFocus();
return;
}
if(userPassword.isEmpty()){
etSignupPassword.setError("Password is required");
//et is focused
etSignupPassword.requestFocus();
return;
}
if(userPassword.length()<6){
etSignupPassword.setError("Password length should be atleast 6 characters");
//request focus
etSignupPassword.requestFocus();
return;
}
//showing progressbar upon regisration process lifetime
progressBar.setVisibility(View.VISIBLE);
//calling firebase register users methods via mAuth instance
mAuth.createUserWithEmailAndPassword(userEmail,userPassword).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
//changing visibility of progress bar to gone upon registration
progressBar.setVisibility(View.GONE);
//checking if the process was successful
//using this task obj
if(task.isSuccessful()){
Toast.makeText(getApplicationContext(),"user registered successfully", Toast.LENGTH_SHORT).show();
}else{
//this line checks whether the email is already registered or not
//using the task obj and FirebasesuthUSerCollisonException
if(task.getException() instanceof FirebaseAuthUserCollisionException){
Toast.makeText(getApplicationContext(),"email already exists",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),task.getException().getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
});
}
我无法弄清楚出了什么问题。帮助表示赞赏。谢谢
解决方案
您正试图从/users
这里阅读:
mDatabase.child("users").orderByChild(userId).addValueEventListener(new ValueEventListener() {
但是您的规则只允许用户访问/users/$uid
. 由于用户对 没有读取权限/users
,因此侦听器被拒绝。
如果要读取用户自己的数据,请读取该特定子节点:
mDatabase.child("users").child(userId).addValueEventListener(new ValueEventListener() {
现在,由于用户对自己的节点具有读取权限,因此将允许侦听器。
推荐阅读
- java - 有没有一种方法可以循环检查 Frame.state 的状态,而无需循环检查中的代码?
- c# - 无法从控件中读取“浮点”类型的值
- javascript - 如何使它在AngularJs中的单个标头上工作
- docker - 错误:无法在 CouchDB Docker 容器中解析 http://any:5984/verifytestdb/
- javascript - 无法在 DOM 中选择元素
- c++ - 将值更改为 C++ 的数组并保存文件
- c - 传递给 pthread 函数调用后访问结构成员
- java - 是否可以为这两个查询设计一个 Google Datastore 索引?
- c - 包含两个双指针的结构,访问第二个双指针时出现段错误
- flutter - Flutter Android 模拟器在使用 VS Code 时只有白色