Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Firebase with Kotlin coroutines

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?

like image 817
Parag Kadam Avatar asked Aug 19 '19 19:08

Parag Kadam


People also ask

What are Kotlin coroutines good for?

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.

How many types of coroutines are in Kotlin?

There are basically 3 scopes in Kotlin coroutines: Global Scope. LifeCycle Scope. ViewModel Scope.


1 Answers

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()
}
like image 82
Valeriy Katkov Avatar answered Oct 22 '22 09:10

Valeriy Katkov