You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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快速完成转换:

  1. 先添加Gson依赖(build.gradle模块级):
implementation 'com.google.code.gson:gson:2.10.1'
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:49:53