I'm trying to access chatting room Using firestore and coroutines.
fun getOwner() {
runBlocking {
var de = async(Dispatchers.IO) {
firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
}
var result = de.await().result
}
But i get error like this :
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: com.example.map_fetchuser_trest, PID: 19329
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source:29)
at com.google.android.gms.tasks.zzu.zzb(Unknown Source:121)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source:12)
at com.example.map_fetchuser_trest.model.Repository$getOwner$1.invokeSuspend(Repository.kt:53)
How can i get chat document? when i use origin api like below, I can access chat room document.
firestore.collection("Chat").document(
"cF7DrENgQ4noWjr3SxKX"
).get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val chatDTO = task.result?.toObject(Appointment::class.java)
}
}
Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages. On Android, coroutines help to manage long-running tasks that might otherwise block the main thread and cause your app to become unresponsive.
A coroutine internally uses a Continuation class to capture the contexts for its execution. Then the dynamic aspect is modeled as a Job class. The use of async usually creates a Deferred job, which is a subclass of the Job class. The CoroutineContext type is required for a coroutine to execute.
Launching a Coroutine as a JobThe launch {} function returns a Job object, on which we can block until all the instructions within the coroutine are complete, or else they throw an exception. The actual execution of a coroutine can also be postponed until we need it with a start argument. If we use CoroutineStart.
Task
is the thing one awaits on, but you wrapped it in another layer of async
. Remove the async
:
fun getOwner() {
runBlocking {
var de = firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
var result = de.await().result
}
}
However, by using runBlocking()
you have shot yourself in the foot and wrote blocking code that just formally uses an async API to no good effect.
To truly benefit from it, you must have a
suspend fun getOwner() = firestore
.collection("Chat")
.document("cF7DrENgQ4noWjr3SxKX")
.get()
.await()
.result
and launch
a coroutine at the place you call it from:
launch {
val owner = getOwner()
// update the GUI
}
This assumes you're calling launch
from an object that is a CoroutineScope
.
val db = FirebaseFirestore.getInstance()
override suspend fun saveBinToDB(bin: Bin): Result<Unit> {
lateinit var result:Result<Unit>
db.collection("bins")
.add(bin)
.addOnSuccessListener { documentReference ->
Log.d(TAG, "DocumentSnapshot written with ID: ${documentReference.id}")
result = Result.Success(Unit)
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding document", e)
result = Result.Error(Exception())
}
.await()
return result
}
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.7"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With