android - Firebase 在注册前验证用户
问题描述
我想在允许注册之前验证用户,但是,即使数据正确,验证也总是在第一次调用时失败
private var isAprroved : Boolean = false
fun signUp(email: String, password: String, idNumber: String): Task<AuthResult>? {
verifyApprovedUser(idNumber)
return if (isAprroved) {
firebaseAuth.createUserWithEmailAndPassword(email, password)
} else {
null
}
}
private fun verifyApprovedUser(idNumber: String) {
dbRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.child(idNumber).exists()) {
updateUserVerified()
}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
fun updateUserVerified() {
isAprroved = true
}
解决方案
isAprroved
总是false
因为verifyApprovedUser
函数调用异步函数,所以createUserWithEmailAndPassword
会在onDataChange
函数之前调用。
要解决此问题,您必须更改为使用TaskCompletionSourceverifyApprovedUser
返回并通过使用in函数进行链接,就像这样。(虽然我没有测试代码)Task<Boolean>
continueWithTask
signUp
科特林版本:
private fun signUp(email: String, password: String, idNumber: String): Task<AuthResult?> {
return verifyApprovedUser(idNumber).continueWithTask { task ->
if (!task.isSuccessful) {
return@continueWithTask Tasks.forException<AuthResult?>(task.exception!!)
}
val verified: Boolean = task.result
if (verified) {
return@continueWithTask FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
} else {
return@continueWithTask Tasks.forResult<AuthResult?>(null)
}
}
}
private fun verifyApprovedUser(idNumber: String): Task<Boolean> {
val tcs: TaskCompletionSource<Boolean> = TaskCompletionSource()
FirebaseDatabase.getInstance().reference.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val verified = dataSnapshot.child(idNumber).exists()
tcs.setResult(verified)
}
override fun onCancelled(databaseError: DatabaseError) {
tcs.setException(databaseError.toException())
}
})
return tcs.task
}
Java版本:
private Task<AuthResult> signUp(String email, String password, String idNumber) {
return verifyApprovedUser(idNumber).continueWithTask(task -> {
if (!task.isSuccessful()) {
return Tasks.forException(task.getException());
}
boolean verified = task.getResult();
if (verified) {
return FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password);
} else {
return Tasks.forResult(null);
}
});
}
private Task<Boolean> verifyApprovedUser(String idNumber) {
TaskCompletionSource<Boolean> tcs = new TaskCompletionSource<>();
FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
boolean verified = dataSnapshot.child(idNumber).exists();
tcs.setResult(verified);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
tcs.setException(databaseError.toException());
}
});
return tcs.getTask();
}
但是,推荐的方法是RxJava
和 Kotlin 的Coroutine
.
另外,您最好了解它是什么Reactive Programming
。
推荐阅读
- react-native - React Native Using ref from a hook
- python-3.x - series.replace not working with regex for pandas > 1.0.5
- ruby-on-rails - Different access name for same model in Ember
- mysql - SQL query return name field from tableA and name field from tableB match with id but tableB doesn't have name field
- c++ - Is there a cost difference between returning a function by reference vs passing the object through a void function?
- rust - How do I integrate a fork of one of the crates I'm using into my project?
- angular - Angular: how to resize Search Filter Pipe
- android - Implementation of library giving duplicate error
- ruby-on-rails - Authorization header is invalid -- one and only one ' ' (space) required in S3 File while accessing
- powerbi - 如何根据两列在 Power BI 中生成排名