Home > Enterprise >  Not able to recover data from firebase before function returns the value
Not able to recover data from firebase before function returns the value

Time:12-31

(Android, Kotlin)
I'm trying to recover data from firebase through a repository and It is happening correctly but in the wrong time

override suspend fun getAllOnline(): MutableStateFlow<ResourceState<List<DocModel>>> {
    val docList: MutableList<DocModel> = mutableListOf()
    auth = FirebaseAuth.getInstance()
    database
        .child(auth.currentUser!!.uid)
        .addValueEventListener(object: ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                for(docs in snapshot.children) {
                    val doc = docs.getValue(DocModel::class.java)
                    docList.add(doc!!)
                }
            }

            override fun onCancelled(error: DatabaseError) {
                return
            }
        })
    return if(docList.isNullOrEmpty()) {
        MutableStateFlow(ResourceState.Empty())
    } else {
        MutableStateFlow(ResourceState.Success(docList))
    }
}

The problem is: my doc list is populated after the return finishes. I've debugged and logged it and the result always come after the function is ended, so it return no data. It is necessary to somehow only allow the return when the data retrieve is completed.
Any suggestions?
Thanks in advance

CodePudding user response:

You can either use await or if you want the code remain this way, you can also use suspendCoroutine like below:

private suspend fun getFirebaseToken(): String? {
    return try {
        val suspendCoroutine = suspendCoroutine<Task<String>> { continuation ->
            FirebaseMessaging.getInstance().token.addOnCompleteListener {
                continuation.resume(it)
            }
        }
        if (suspendCoroutine.isSuccessful && suspendCoroutine.result != null)
            suspendCoroutine.result
        else null
    } catch (e: Exception) {
        e logAll TAG
        null
    }
}

suspendCoroutine<Task> can be replaced suspendCoroutine<MutableList>

And you will pass docList in "continuation.resume(docList)" instead of "it":

Your final code will look like this:

override suspend fun getAllOnline(): MutableStateFlow<ResourceState<List<DocModel>>> {

auth = FirebaseAuth.getInstance()

val docList = suspendCoroutine<MutableList<DocModel>>{ continuation->
  database
    .child(auth.currentUser!!.uid)
    .addValueEventListener(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            val docList: MutableList<DocModel> = mutableListOf()
            for(docs in snapshot.children) {
                val doc = docs.getValue(DocModel::class.java)
                docList.add(doc!!)
            }
            continuation.resume(docList)
        }

        override fun onCancelled(error: DatabaseError) {
            continuation.resume(emptyList<DocModel>())
        }
    })
}
return if(docList.isSuccessful && docList.result != null && 
       docList.result.isNullOrEmpty()) {
    MutableStateFlow(ResourceState.Success(docList.result))
} else {
    MutableStateFlow(ResourceState.Empty())
}

}

  • Related