我有一个注册屏幕。在那个屏幕上,我得到了电子邮件,电子邮件和密码。Firestore API会自动检查电子邮件是否在使用中,但我想向用户显示输入的电子邮件是否在使用中。为此,我使用了以下代码片段:
fun userExists(element1 : String, element2 : String) : Boolean {
val db : FirebaseFirestore = FirebaseFirestore.getInstance()
val dbUsers : CollectionReference = db.collection("user")
var isExists : Boolean = false
dbUsers.whereEqualTo(element1, element2).get().addOnSuccessListener {
// if true it is empty and it is not exists.
isExists = it.documents.isNotEmpty()
}
return isExists
但在这里它跳过并继续,而不返回正确的值。当我单独尝试时,它工作得很好,我知道数据是否存在,但当我这样使用它时,它不工作。我尝试添加await(),但它也没有工作。为了在@Composable函数下运行它,我先让函数挂起,然后在rememberCoroutine下调用了这个userlogists函数,但也无法运行它。我想要的只是检查例如userName:user 1234是否存在。先谢了。
编辑:整个代码。
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignUpScreen(navigation: NavController, auth: FirebaseAuth) {
var userName by remember { mutableStateOf("") }
var userEmail by remember { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
var passwordVisible by rememberSaveable { mutableStateOf(false) }
val context = LocalContext.current
val sharedPrefMail = context.getSharedPreferences("userEmail", Context.MODE_PRIVATE)
val sharedPrefName = context.getSharedPreferences("userName", Context.MODE_PRIVATE)
val sharedPrefScore = context.getSharedPreferences("highScore", Context.MODE_PRIVATE)
val db : FirebaseFirestore = FirebaseFirestore.getInstance()
val dbUsers : CollectionReference = db.collection("user")
val buttonSize = with(LocalDensity.current) {
(300f).toDp()
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(vertical = buttonSize),
horizontalAlignment = Alignment.CenterHorizontally
) {
{...}
// Toast message is not shown. Use PopUp message
Button(onClick = {
if (userEmail == "" || password == "" || userName == "") {
Toast.makeText(context, "PLEASE ENTER EMAIL, USERNAME AND PASSWORD", Toast.LENGTH_LONG).show()
} else if (userExists("userName", userName)) {
Toast.makeText(context, "USERNAME IS IN USE", Toast.LENGTH_LONG).show()
} else {
auth.createUserWithEmailAndPassword(userEmail, password).addOnSuccessListener {
// User creation is successful
val user = UserObj(userEmail, userName, "0")
dbUsers.add(user).addOnSuccessListener {
Toast.makeText(context, "USER CREATED SUCCESSFULLY", Toast.LENGTH_LONG).show()
sharedPrefMail.edit().putString("userMail", userEmail).apply()
sharedPrefName.edit().putString("userName", userName).apply()
sharedPrefScore.edit().putString("highScore", "0").apply()
}
navigation.navigate("FirstScreen")
}.addOnFailureListener {
Toast.makeText(context, "COULDN'T CREATE USER", Toast.LENGTH_LONG).show()
println(it.localizedMessage)
}
}
},
modifier = Modifier.size(buttonSize, buttonSize/3)
) {
Text("SIGN UP")
}
}
}
3条答案
按热度按时间avwztpqn1#
不能将
isExists
作为函数的结果返回。Firebase API是异步的。为了解决这个问题,你必须使用一个总是相同的解决方案。任何需要从Firestore获取数据的代码都需要在onSuccess()
函数内部或从那里调用。然而,更现代的方法是使用Kotlin Coroutines。我尝试添加await(),但它也不起作用。
这句话没有提供足够的信息,所以我们可以帮助。然而,当你调用await()时,它意味着它将一直等待任务的完成,而不会阻塞线程。请注意,此函数是
suspend
函数,不是blocking
函数。所以你的函数应该看起来像这样:这个方法将检查查询的结果是否为空。
2ul0zpep2#
你不能这样做,因为这是一个异步操作。但是你可以用flow和suspend函数来做。
像这样收集,
yyhrrdl83#
在@Faruk Karaca的回答之前,我解决了这个问题。我指定这一点,因为它可能工作以及idk。
下面是整个代码:
在mainScope.launch下我实现了我的suspend函数。