2015-11-09 43 views
2

我是Firebase的新用户。我使用验证电子邮件地址和密码的用户 -认证后读取数据时Firebase权限被拒绝

final Firebase ref = new Firebase("https://app.firebaseio.com"); 
ref.authWithPassword("[email protected]", "password", new Firebase.AuthResultHandler() { 

    @Override 
    public void onAuthenticated(AuthData authData) { 
     System.out.println("User ID: " + authData.getUid()); 
     getData(ref); 
    } 

    @Override 
    public void onAuthenticationError(FirebaseError firebaseError) { 
    } 
}); 

但认证后,当我读数据时,我得到Permission Denied

private void getData(Query ref) { 
    ref.addValueEventListener(new ValueEventListener() { 

     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      System.out.println(snapshot.getValue()); 
     } 

     @Override 
     public void onCancelled(FirebaseError firebaseError) { 
      System.out.println("The read failed: " + firebaseError.getMessage()); 
     } 
    }); 
} 

这些是Firebase规则。

{ 
    "rules": { 
     "users": { 
      "$uid": { 
       ".read": "auth !== null && auth.provider === 'password'" 
      } 
     } 
    } 
} 

回答

7

Firebase的权限模型只允许用户访问您明确授予访问权限的数据。由于在您的安全规则中,您只能访问/users/$uid,因此用户无法从根/读取。 Firebase文档覆盖了"rules cascade"

您似乎想要使用安全规则来过滤数据,而这对于Firebase的安全模型来说是不可能的。见火力地堡文档中的部分"rules are not filters"以及这些以前的问题和答案:

最简单的解决方案是允许读取users节点:

{ 
    "rules": { 
     "users": { 
      ".read": "auth !== null && auth.provider === 'password'" 
     } 
    } 
} 

然后查询该级别:

getData(ref.child("users")); 
+0

的规则级联好一点,谢谢分享更多信息的规则。我还想提及另一个修复使用[相同的火力点sdks](https://stackoverflow.com/questions/38657873/firebase-permission-denied-after-auth),这对我工作。 – raiser00

2

我用一个稍微不同的方式从我的数据库中读取此异常,但是这是我如何解决这个问题。

首先,我的数据库规则看起来很喜欢这样的:

mAuthListener = new FirebaseAuth.AuthStateListener() { 
     @Override 
     public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
      user = firebaseAuth.getCurrentUser(); 
      if (user != null) { 
       // User is signed in 
       Log.e(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 
      } else { 
       // User is signed out 
       Log.e(TAG, "onAuthStateChanged:signed_out"); 
      } 
      // ... 
     } 
    }; 
    ... 
    Student student = new Student(); 
    student.setPhoneNumber("+23480547455343"); 
    student.setCountryOfOrigin("Nigeria"); 
    mDatabaseReference.child("student").child(user.getUid()).setValue(student). 
       addOnCompleteListener(DetailsCaptureActivity.this, 
            new OnCompleteListener<Void>() { 
    ... 
    }); 

注意如何:

{ 
"rules": { 
    "student": { 
    "$uid": { 
     ".write": "auth != null && auth.uid == $uid", 
     ".read": "auth != null && auth.uid == $uid" 
     } 
    } 
    } 
} 

早前,写的学生数据库,我在活动中使用此代码子女姓名(学生)是否与Firebase数据规则中的子女姓名相符?

现在阅读本用户的数据,我这样做:

//Set up an AuthStateListener that responds to changes in the user's sign-in state: 
    mAuthListener = new FirebaseAuth.AuthStateListener() { 
     @Override 
     public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
      user = firebaseAuth.getCurrentUser(); 
      if (user != null) { 

        databaseReference = firebaseDatabase.getReference().child("student").child(user.getUid()); 
        databaseReference.addValueEventListener(new ValueEventListener() { 
         @Override 
         public void onDataChange(DataSnapshot dataSnapshot) { 
          Student student = dataSnapshot.getValue(Student.class); 
          phoneNumberTextView.setText(student.getPhoneNumber()); 
         } 

         @Override 
         public void onCancelled(DatabaseError databaseError) { 

          Log.e(TAG, databaseError.getMessage()); 
         } 
        }); 

      } else { 
       Log.e(TAG, "onAuthStateChanged:signed_out"); 
      } 
     } 
    }; 

我得到的权限被拒绝异常,如果我只做:

databaseReference = firebaseDatabase.getReference().child(user.getUid()); 
0

的问题是,火力地堡有一个错误,在验证之后,您必须等到用户出现在FirebaseAuth之后,然后才能使用它。

我所做的是等待它出现,像

Observable.fromCallable(() -> signInImpl()) 
     .map(this::toFirebaseUser) 
     .map(this::waitForUserToAppearInAuthenticator) 
     .flatMap(this::doSomethingInDatabase); 

@NonNull 
private FirebaseUser waitForUserToAppearInAuthenticator(@NonNull final FirebaseUser user) { 
    final CountDownLatch cdl = new CountDownLatch(1); 
    final FirebaseAuth.AuthStateListener l = firebaseAuth -> { 
     final FirebaseUser cu = firebaseAuth.getCurrentUser(); 
     if (cu != null && user.getUid().equals(cu.getUid())) { 
      cdl.countDown(); 
     } 
    }; 
    mFirebaseAuth.addAuthStateListener(l); 
    try { 
     cdl.await(20, TimeUnit.SECONDS); 
    } catch (InterruptedException e) { 
     throw new RuntimeException(e); 
    } finally { 
     mFirebaseAuth.removeAuthStateListener(l); 
    } 

    return user; 
}