从Firebase获取数据时java.util.HashMap无法转为Product列表求助
问题:Firestore数据转自定义Product列表时出现类型转换错误
问题现象
从Firebase Firestore读取嵌套的products列表时,执行document.get("products") as MutableList<Product>抛出java.util.HashMap cannot be cast to [你的包名].Product错误,尝试转换为ListArray和Array后问题仍存在。
问题代码
fun getDeliveryList(userId: String): LiveData<MutableList<Invoice>> { val mutableData = MutableLiveData<MutableList<Invoice>>() FirebaseFirestore.getInstance().collection(Constants.ENVIRONMENT).document("users").collection("users").document(userId).collection("invoices").get().addOnSuccessListener { result -> val invoices = mutableListOf<Invoice>() for(document in result) { val uuid = document.getString("uuid") val invoiceURL = document.getString("invoiceURL") val products = document.get("products") as MutableList<Product> val createdAt = document.getString("createdAt") val isSponsor = document.getString("isSponsor") val invoice = Invoice(uuid!!, invoiceURL!!, products, createdAt!!, isSponsor!!) invoices.add(invoice) } mutableData.value = invoices } return mutableData }
原因分析
Firebase Firestore不会自动将嵌套的JSON对象(存储为HashMap)转换为自定义的Product实体类,直接强制类型转换必然失败——因为返回的是List<HashMap<String, Any>>,而非List<Product>。
解决方案
方案一:手动遍历映射(无需额外依赖)
直接遍历Firestore返回的HashMap列表,逐个字段映射到Product对象:
// 替换原代码中products的获取逻辑 val productsRaw = document.get("products") as? MutableList<HashMap<String, Any>> ?: mutableListOf() val products = productsRaw.map { productMap -> Product( // 根据你的Product类属性,从map中取出对应值,示例如下: productId = productMap["productId"] as String, productName = productMap["productName"] as String, price = productMap["price"] as Double, quantity = productMap["quantity"] as Int // 补充你自己的所有Product属性 ) }.toMutableList()
方案二:用Gson自动序列化(推荐,减少手动代码)
如果Product类的属性名和Firestore中的字段完全匹配,可以用Gson快速完成转换:
- 先添加Gson依赖(build.gradle模块级):
implementation 'com.google.code.gson:gson:2.10.1'
- 修改products转换逻辑:
val productsJson = Gson().toJson(document.get("products")) val products = Gson().fromJson<List<Product>>( productsJson, object : TypeToken<List<Product>>() {}.type ).toMutableList()
完整修改后的代码示例
fun getDeliveryList(userId: String): LiveData<MutableList<Invoice>> { val mutableData = MutableLiveData<MutableList<Invoice>>() FirebaseFirestore.getInstance() .collection(Constants.ENVIRONMENT) .document("users") .collection("users") .document(userId) .collection("invoices") .get() .addOnSuccessListener { result -> val invoices = mutableListOf<Invoice>() for (document in result) { // 空值处理:跳过字段不完整的文档 val uuid = document.getString("uuid") ?: continue val invoiceURL = document.getString("invoiceURL") ?: continue val createdAt = document.getString("createdAt") ?: continue val isSponsor = document.getString("isSponsor") ?: continue // 转换products列表(这里用手动映射示例) val productsRaw = document.get("products") as? MutableList<HashMap<String, Any>> ?: mutableListOf() val products = productsRaw.map { map -> Product( productId = map["productId"] as String, productName = map["productName"] as String, price = map["price"] as Double, quantity = map["quantity"] as Int ) }.toMutableList() val invoice = Invoice(uuid, invoiceURL, products, createdAt, isSponsor) invoices.add(invoice) } mutableData.value = invoices } return mutableData }
注意事项
- 确保Product类的属性名与Firestore中存储的字段名完全一致(大小写敏感)
- 必须处理空值:用
?: continue跳过字段缺失的无效文档,避免空指针异常 - 如果Firestore中存储的数值是
Long类型,转换时要对应为Long而非Int,避免类型转换错误
内容的提问来源于stack exchange,提问作者Kevinho Morales
相关产品推荐
相关产品推荐

