Kotlin:要素がリストに追加されていません[重複]
Aug 22 2020
kotlinでAndroidアプリを作成していますが、現在、奇妙な問題に直面しています。問題がこれである関数:
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()
}
ここにユーザーのIDがいくつかあり、これらのIDに基づいて、Firebase Cloud Firestoreデータベースから名前をフェッチしています。データは正常にフェッチされておりnamelist
、フェッチブロック内で初めて印刷するときに、要素が追加されています。ただし、nameList
フェッチブロックの外側を印刷すると、要素が追加されないことがわかります。画像を添付しました。

ご覧のとおり、要素が追加されています。しかしその後、要素は消え、リストは空になります。

なぜこれが起こっているのか、私は本当に混乱しています。
回答
2 aminography Aug 22 2020 at 08:32
原因は、非同期ジョブを同期ジョブとして機能させたいためです。私たちが知っているように、からのそのようなデータの取得firestore
は非同期プロシージャです(に注意してくださいaddOnSuccessListener
)。したがって、関数がnameList
(最後と同様に)戻るとき、println
からの結果のいずれかがfirestore
まだ取得されていないため、関数は空です!
オブジェクトをDocumentReference.get()
返すので、Task
それを待つことができます。したがって、関数は次のようになります。
@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()
}
この場合、この関数は(メインスレッドではなく)ワーカースレッドで呼び出す必要があることに注意してください。