'Assign variable a value oustide a listener in Kotlin [duplicate]

I'm kinda new to Kotlin and Firebase.

I have this problem and I can't figure out why it happens.
I'm trying to get the Firebase Cloud Firestore documents count and since there isn't a built-in .count() I'm trying to do it by myself. Right now I have 10 documents inside a collection. The count works only inside the listener because when I try to use counter outside it, it gives me 0

var counter = 0

database.collection("collection").get()
     .addOnCompleteListener { task ->
          counter = task.result.size()
          Log.d("Documents count inside listener", counter.toString()) // 10
     }

When I log "counter" inside the listener I get the correct number
But when I log it outside the listener it gives me 0

Log.d("Documents count outside listener", counter.toString()) // 0

val map = hashMapOf(
     "_id" to counter
)

So what's happening and why ? What am I doing wrong ?
Sorry if it is a stupid question



Solution 1:[1]

You are getting different results because, the callback happens a bit after you have logged the counter. The value of counter is change later in time.

You need to make your count function a suspended function then resume the coroutine once the callback is called.

 suspend fun CollectionReference.count() = suspendCancellableCoroutine<Int> { continuation ->
        get().addOnCompleteListener { 
            continuation.resume(it.result.size())
        }.addOnFailureListener { 
            continuation.resumeWithException(it)
        }.addOnCanceledListener { 
            continuation.cancel()
        }
    }

Then usage would be like:

coroutineScope.launch{
 val counter = database.collection("collection").count() 
 Log.d("Documents count", "$counter")
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nikola Despotoski