无法从Firebase读取数据-Firebase DatabaseError:权限被拒绝

时间:2018-11-25 18:33:11

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

我创建了一个简单的应用程序,用户可以在该应用程序上注册登录。身份验证工作正常。我还添加了一个实时数据库。当我尝试从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 Console 我还包括登录和注册方法:

登录方法:

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

我不知道出了什么问题。感谢帮助。谢谢

2 个答案:

答案 0 :(得分:1)

您正在尝试从此处的/users中读取内容:

mDatabase.child("users").orderByChild(userId).addValueEventListener(new ValueEventListener() {

但是您的规则仅授予用户访问/users/$uid的权限。由于用户没有/users的读取权限,因此监听器将被拒绝。

如果要读取用户自己的数据,请读取特定的子节点:

mDatabase.child("users").child(userId).addValueEventListener(new ValueEventListener() {

现在,由于用户具有对自己节点的读取权限,因此将允许侦听器。

答案 1 :(得分:0)

确保应用名称和客户端ID与Firebase控制台中的相同。

如果不确定从项目控制台重新下载google-services.json并将其添加到您的项目中。

并在开发和测试期间将您的规则更改为此

{
  "rules": {
    ".read": true,
    ".write": true
  }
}