private fun getUserIdByEmail(email: String): String {
var userId = ""
CoroutineScope(IO).launch {
try {
val querySnapshot = user3CollectionRef
.whereEqualTo("userEmail", email)
.get()
.await()
if (querySnapshot.documents.isNotEmpty()) {
for (document in querySnapshot.documents) {
userId = document.id
}
} else {
withContext(Dispatchers.Main) {
toast("No Match")
}
}
} catch(e: Exception) {
withContext(Dispatchers.Main) {
toast(e.message.toString())
}
}
Log.e("a7a", userId)
withContext(Dispatchers.Default) {
return userId
}
}
}
That’s the function I’m using to query through firebase documents, the thing is I want to return the userId which is a variable that I defined in the first line of the function, when I place the return block outside the coroutine scope, it returns an empty string, how do I return it inside the scope so it can run when the coroutine is finished, or any other way to return after the coroutine is finished
>Solution :
In order to make a function returns a pending value; it should be a suspend function to return the value asynchronously.
Then, instead of the launch builder, the async/await builder can be used to return a Deferredvalue.
await() waits until it’s assigned a value by the Coroutine
Applying that in code:
private suspend fun getUserIdByEmail(email: String): String {
val userId = CoroutineScope(IO).async {
var tempId = ""
try {
val querySnapshot = user3CollectionRef
.whereEqualTo("userEmail", email)
.get()
.await()
if (querySnapshot.documents.isNotEmpty()) {
for (document in querySnapshot.documents) {
tempId = document.id
}
} else {
withContext(Dispatchers.Main) {
toast("No Match")
}
}
} catch(e: Exception) {
withContext(Dispatchers.Main) {
toast(e.message.toString())
}
}
Log.e("a7a", tempId)
withContext(Dispatchers.Default) {
return@async tempId
}
}
return userId.await() // waits until it's assigned a value from the Coroutine
}