I am using Kotlin coroutines in my app and have chosen firebase as my choice for database and storage. After exploring firebase I realized that all its APIs are asynchronous and the result of the asynchronous calls are returned in a callback, and getting rid of callbacks is the main reason why I am using Kotlin coroutines in my app.
This is the code I have written to upload a file to firebase cloud storage but it is giving "Task is not yet complete" error.
private suspend fun saveImage(filePath: String): String? {
val storage = FirebaseStorage.getInstance("gs://myapp-9a648.appspot.com/")
val storageRef = storage.reference
val file = Uri.fromFile(File(filePath))
val imageRef = storageRef.child("images/${file.lastPathSegment}")
return withContext(Dispatchers.IO) {
imageRef.putFile(file).snapshot.storage.downloadUrl.result.toString()
}
}
E/AndroidRuntime: FATAL EXCEPTION: main Process: pk.com.kotlinapp, PID: 7491 java.lang.IllegalStateException: Task is not yet complete at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source) at com.google.android.gms.tasks.zzu.zzb(Unknown Source) at com.google.android.gms.tasks.zzu.getResult(Unknown Source) at prk.com.kotlinapptest.DatabaseManager$saveImage$2.invokeSuspend(DatabaseManager.kt:28) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)
Is there any way I can upload a file to firebase cloud storage and get back the download URL without getting the download URL in its success callback?
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.
There are basically 3 scopes in Kotlin coroutines: Global Scope. LifeCycle Scope. ViewModel Scope.
kotlinx-coroutines-play-services
library provides await extension function that allows to await the task completion, like:
...
dependencies {
...
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.1"
}
return withContext(Dispatchers.IO) {
imageRef
.putFile(file)
.await() // await() instead of snapshot
.storage
.downloadUrl
.await() // await the url
.toString()
}
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