我创建了一个简单的应用程序,用户可以在该应用程序上注册登录。身份验证工作正常。我还添加了一个实时数据库。当我尝试从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();
}
}
}
});
}
我不知道出了什么问题。感谢帮助。谢谢
答案 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
}
}