Jetpack Compose读取Cloud Firestore报错:For-loop需iterator()方法
解决Jetpack Compose中Firestore读取数据的迭代器错误
在Jetpack Compose中从Cloud Firestore读取数据时,遇到错误提示:"For-loop range must have an 'iterator()' method",错误指向for (document in documents)语句中的documents变量。以下是问题代码分析及解决方案:
初始代码
fun Varer() { var firestore: FirebaseFirestore = FirebaseFirestore.getInstance() var docRef = firestore.collection("varer").document("varer") var source = Source.DEFAULT docRef.get(source).addOnSuccessListener { documents -> for (document in documents) { Log.d(TAG, "${document.id} => ${document.data}") var v1 = VareFB( tittel = document["tittel"].toString(), pris = document.getDouble("pris"), beskrivelse = document["beskrivelse"].toString(), bildeID = document["bildeID"].toString(), ) varerListe.add(v1) Log.d(TAG, document["tittel"].toString()) Log.d(TAG, v1.toString()) } } .addOnFailureListener { exception -> Log.w(TAG, "Feil med henting av varer: ", exception) } }
data class VareFB ( val tittel: String, val pris: Double?, val beskrivelse: String, val bildeID: String, ) { @Exclude fun toMap(): Map<String, Any?> { return mapOf( "tittel" to tittel, "pris" to pris, "beskrivelse" to beskrivelse, "bildeID" to bildeID, ) } }
object VarerObject { var varerListe = mutableListOf<VareFB>() }
修改后的代码
fun Varer() { var firestore: FirebaseFirestore = FirebaseFirestore.getInstance() var docRef = firestore.collection("varer").document("varer") var source = Source.DEFAULT docRef.get(source).addOnSuccessListener { snapshot -> for (document in snapshot.documents) { Log.d(TAG, "${document.id} => ${document.data}") var v1 = VareFB( tittel = document["tittel"].toString(), pris = document.getDouble("pris"), beskrivelse = document["beskrivelse"].toString(), bildeID = document["bildeID"].toString(), ) varerListe.add(v1) Log.d(TAG, document["tittel"].toString()) Log.d(TAG, v1.toString()) } } .addOnFailureListener { exception -> Log.w(TAG, "Feil med henting av varer: ", exception) } }
问题分析
初始代码错误原因:
调用firestore.collection("varer").document("varer")获取的是单个文档,对应DocumentSnapshot对象。该对象不是可迭代集合,无法用for (document in documents)遍历,因此触发迭代器错误。修改后代码的问题:
DocumentSnapshot没有documents属性,snapshot.documents会导致新的编译错误,本质是混淆了单个文档与集合查询的区别。
解决方案
根据数据结构分两种情况处理:
情况1:varer是集合,包含多个文档
若varer集合下有多个独立商品文档,直接查询整个集合:
fun fetchVarer() { val firestore = FirebaseFirestore.getInstance() val collectionRef = firestore.collection("varer") val source = Source.DEFAULT collectionRef.get(source).addOnSuccessListener { querySnapshot -> val newVarerList = mutableListOf<VareFB>() // querySnapshot.documents是可迭代的文档列表 for (document in querySnapshot.documents) { Log.d(TAG, "${document.id} => ${document.data}") val vare = VareFB( tittel = document["tittel"].toString(), pris = document.getDouble("pris"), beskrivelse = document["beskrivelse"].toString(), bildeID = document["bildeID"].toString(), ) newVarerList.add(vare) } // 更新全局列表(Compose中建议用MutableStateListOf实现UI自动刷新) VarerObject.varerListe.clear() VarerObject.varerListe.addAll(newVarerList) } .addOnFailureListener { exception -> Log.w(TAG, "Feil med henting av varer: ", exception) } }
情况2:varer是单个文档,内部包含商品数组
若单个varer文档中存储了商品数组字段,需取出数组再遍历:
fun fetchVarer() { val firestore = FirebaseFirestore.getInstance() val docRef = firestore.collection("varer").document("varer") val source = Source.DEFAULT docRef.get(source).addOnSuccessListener { documentSnapshot -> // 取出文档中的数组字段(假设字段名为"varer") val varerArray = documentSnapshot.get("varer") as? List<Map<String, Any>> varerArray?.forEach { item -> val vare = VareFB( tittel = item["tittel"].toString(), pris = item["pris"] as? Double, beskrivelse = item["beskrivelse"].toString(), bildeID = item["bildeID"].toString(), ) VarerObject.varerListe.add(vare) } } .addOnFailureListener { exception -> Log.w(TAG, "Feil med henting av varer: ", exception) } }
额外提示
在Jetpack Compose中,直接修改全局可变列表varerListe不会触发UI自动刷新。建议将varerListe改为mutableStateListOf(),或使用StateFlow管理数据状态,确保数据更新时UI同步刷新。
内容的提问来源于stack exchange,提问作者Magnus Jernberg
相关产品推荐
相关产品推荐

