Kotlin: elemento non aggiunto all'elenco [duplicato]
Sto creando un'app per Android con kotlin, ma al momento sto affrontando uno strano problema. La funzione in cui il problema è questo:
private fun getName(uids:List<String>):List<String> {
val nameList = mutableListOf<String>()
for (uid in uids) {
Firebase.firestore.collection("users").whereEqualTo("id", uid).get().addOnSuccessListener { documents ->
val name = documents.documents[0]["name"] as String
println("The name is $name") nameList.add(name) println("The namelist is $nameList")
}
println("The data above is $nameList") } println("The datahere is $nameList")
return nameList.toList()
}
Qui ho alcuni ID dell'utente e in base a questi ID sto recuperando il nome dal database Firebase Cloud Firestore, i dati vengono recuperati con successo e quando stampo la namelist
prima volta all'interno del blocco di recupero, viene aggiunto un elemento. Tuttavia, quando stampo l' nameList
esterno del blocco di recupero, vedo che l'elemento non si aggiunge. Ho allegato un'immagine.

Come puoi vedere l'elemento è stato aggiunto. Ma dopo di ciò, l'elemento scompare e l'elenco diventa vuoto.

Sono davvero confuso sul motivo per cui questo sta accadendo.
Risposte
La causa è che desideri che un lavoro asincrono agisca come uno di sincronizzazione. Come sappiamo, il recupero dei dati da firestore
è una procedura asincrona (attenzione a addOnSuccessListener
). Quindi, quando la funzione ritorna nameList
(così come l'ultima println
), è vuota perché nessuno dei risultati di firestore
non è stato ancora recuperato!
Quando DocumentReference.get()
restituisce un Task
oggetto è possibile attendere su di esso. Quindi, la tua funzione potrebbe essere qualcosa del genere:
@WorkerThread
private fun getName(uids: List<String>) {
val nameList = mutableListOf<String>()
for (uid in uids) {
val task = Firebase.firestore.collection("users").whereEqualTo("id", uid).get()
val documentSnapshot = Tasks.await(task)
val name = documentSnapshot.documents[0]["name"] as String
nameList.add(name)
}
nameList.toList()
}
Si noti che in questo caso, è necessario chiamare questa funzione in un thread di lavoro (non thread principale).