警报对话框肯定按钮不等待异步火存储请求调用完成



我有一个AlertDialog,它具有用于登录用户的自定义布局,通过检查Firestore中是否存在用户的电子邮件来检查这是否是用户第一次登录。

private fun showSignInDialog() {
val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
builder.setTitle("Sign In")
val inflater = requireActivity().layoutInflater
val dialogView = inflater.inflate(R.layout.dialog_sign_in, null)
builder.setView(dialogView)
val editEmail = dialogView.findViewById<EditText>(R.id.edit_email)
val editPassword = dialogView.findViewById<EditText>(R.id.edit_password)
builder.setPositiveButton("OK") { _, _ ->
val email = editEmail.text.toString()
val password = editPassword.text.toString()
signInWithEmail(email, password)
}
builder.setNegativeButton("Cancel") { dialog, _ -> dialog.cancel() }
builder.create().show()
}
private fun signInWithEmail(email: String, password: String) {
auth = Firebase.auth
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(requireActivity()) { task ->
if (task.isSuccessful) {
Log.d(TAG, "signInWithEmail:success")
val signedInEmail = auth.currentUser?.email
firestoreService = FirestoreService()
firestoreService.doesUserAlreadyExists(object : UserCallback {
override fun onCallback(dRef: String) {
Log.d(TAG, "dRef = $dRef")
if (dRef.isEmpty())
findNavController().navigate(R.id.action_signIn_to_ceateProfile)
else
findNavController().navigate(R.id.action_signIn_to_main)
}
}, signedInEmail!!)
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.exception)
Toast.makeText(
requireContext(), "Authentication failed.",
Toast.LENGTH_SHORT
).show()
}
}
}

FirestoreService.kt

class FirestoreService {
private val db = Firebase.firestore
fun doesUserAlreadyExists(callback: UserCallback, email: String) {
db.collection("Users")
.whereEqualTo("email", email).get()
.addOnSuccessListener { documents ->
for (document in documents) {
val docRef = document.id
callback.onCallback(docRef)
Log.d(TAG, "docRef = $docRef")
}
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding User document", e)
}
}
}

但是这个doesUserAlreadyExists从来没有被执行过,这可能是因为这个方法是异步的,并且在异步回调完成后没有什么可返回的,因为对话框在那个时候被破坏了。我怎样才能做到这一点?

更新:

我在片段而不是对话框上尝试了相同的逻辑,结果相同。这似乎与addOnCompleteListener中的firestoreService.doesUserAlreadyExists有关,因为一个异步回调在另一个异步回叫中。如何解决此问题?

问题是没有"用户";集合检查,因为我已经删除了";用户";集合,因此未调用addOnSuccessListeneraddOnFailureListener

我希望在集合不存在时抛出异常。

addOnSuccessListener侦听器相比,最好使用addOnCompleteListener,因为无论什么都可以保证它被触发

例如:

db.collection(USER_COLLECTION)
.whereEqualTo("email", email).get()
.addOnCompleteListener { task ->
if(task.isSuccessful){
for (document in task.result) {
if (document.exists()) {
//..
}
}
}
else{
//..
}
}

最新更新