Coroutine JobCancellationException on updating Firestore document

Viewed 216

Upon calling my ViewModel's saveUser(), the Firebase Firestore document is updated successfully, but the coroutine Job gets cancelled, catching a JobCancellationException, and the log "User #${user.id} saved !" is never printed. Where does this cancellation comes from and how can it complete instead ?

// ViewModel.kt

fun saveUser(user: User) {
    viewModelScope.launch(Dispatchers.IO) {
        Repository.saveUser(user)
        Log.d("test", "User #${user.id} saved !")
    }
}

// Repository.kt

suspend fun saveUser(user: User) {
    val documentReference = db
        .collection(USERS_COLLECTION).document(user.id)

    try {
        documentReference.set(user).await()
        Log.d("test", "Good")
    } catch (e: Exception) {
        Log.e("test", "Not good") // catches a JobCancellationException
    }
}
1 Answers

Something is cancelling the Job, and your coroutine is appropriately cooperating.

It could be that your ViewModel is being cleared, since you are launching the coroutine using viewModelScope. The ViewModel should not get destroyed unless its owner (Fragment or Activity) is being destroyed. Are you doing something like trying to call finish() on your Activity while this is happening, or performing a Fragment transaction?

Or, it could be that something else in the coroutine context is cancelling the Job due to an error. My guess would be that the call to documentReference.set(user) is causing some error, and await() is cancelling the job, maybe.

Also make sure your dependencies for Firestore, Jetpack, and the KTX extensions are up to date. This may be a bug that has been fixed.

Related