[英]Firebase verify user before sign up
I want to verify a user before I can allow signup, however, the verification always fails on the first call even when data is correct我想在允许注册之前验证用户,但是,即使数据正确,验证也总是在第一次调用时失败
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
is always false
since verifyApprovedUser
function calls an asynchronous function, so createUserWithEmailAndPassword
will be called before onDataChange
function. isAprroved
始终为false
,因为verifyApprovedUser
function 调用异步 function,因此createUserWithEmailAndPassword
将在onDataChange
function 之前调用。
To fix this, you have to change verifyApprovedUser
to return Task<Boolean>
with using TaskCompletionSource and chaining by using continueWithTask
in signUp
function, something like this.要解决此问题,您必须更改verifyApprovedUser
以使用TaskCompletionSource返回Task<Boolean>
并通过在signUp
function 中使用continueWithTask
进行链接,如下所示。 (I didn't test code though) (虽然我没有测试代码)
Kotlin Version: Kotlin 版本:
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 Version: 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();
}
However, a recommended approach would be RxJava
and Kotlin's Coroutine
.但是,推荐的方法是RxJava
和 Kotlin 的Coroutine
。
Plus, you would better to learn what Reactive Programming
is.另外,您最好了解什么是Reactive Programming
。
I dont know how efficient this is, but this is how i managed to implement我不知道这有多有效,但这就是我设法实施的方式
val approvedUsersList : MutableList<String> = ArrayList()
fun signUp(email: String, password: String, idNumber: String): Task<AuthResult>? {
verifyApprovedUsers()
if (idNumber in approvedUsersList){
return firebaseAuth.createUserWithEmailAndPassword(email, password)
} else {
return null
}
}
private fun verifyApprovedUsers() {
dbRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
approvedUsersList.clear()
for (data: DataSnapshot in snapshot.children) {
approvedUsersList.add(data.value.toString())
}
}
This is how my Login Activity Verifies if I already logged in before.这就是我的登录活动验证我之前是否已经登录的方式。
private fun verifyIfUserIsLoggedIn() { // Checks if user has already logged in
val uid = FirebaseAuth.getInstance().uid
// This checks if there is a present UID in your Activity
// If UID == null, intent closes the CurrentActivity and throws you back in RegisterActivity
if (uid == null) {
val intent = Intent(this, RegisterActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK) // Clears previous activity when inflating the new one
startActivity(intent)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.