Firestore读取时模型新增字段但库中无对应字段报错如何处理?
问题根因
本次崩溃是Firestore反序列化规则和Kotlin模型类的编译特性共同导致的,核心原因有两个:
- Firestore将Document转换为自定义类时,依赖反射调用类的无参构造方法创建实例,虽然你给所有字段都设置了默认值,但如果模型类被混淆、或者缺少对应注解,Kotlin编译后可能不会生成符合要求的无参构造,导致反射创建实例失败。
- 模型类没有配置Firestore的字段兼容注解,存量数据缺少新增字段时,反序列化过程会因为字段不匹配抛出异常。
解决方案
按以下步骤修改即可完全兼容存量数据:
1. 给模型类添加必要注解
添加@IgnoreExtraProperties注解让Firestore反序列化时自动忽略不匹配的字段(包括数据库中不存在的新增字段、类中不存在的数据库冗余字段),添加@Keep注解防止混淆时破坏类结构:
import androidx.annotation.Keep import com.google.firebase.firestore.IgnoreExtraProperties import kotlinx.parcelize.Parcelize import android.os.Parcelable @Keep @IgnoreExtraProperties @Parcelize data class ProductDetails( var product_id: String? = "", val title: String = "", val mrp: String= "0.00", val price: String = "0.00", val description: String = "", var min_order_quantity: String="", var max_order_quantity: String="", ) : Parcelable
2. 配置模型类混淆规则
在app模块的proguard-rules.pro文件中添加模型类所在包的不混淆规则,避免打包后反射找不到类成员:
-keep class com.abc.xyz.models.** { *; }
3. 可选:添加单条数据解析兜底
如果担心极端场景下存在脏数据,可以给单条数据的解析逻辑加异常捕获,避免单条数据异常导致整个列表加载失败:
mFireStore.collection("product_details") .get() .addOnCompleteListener { if (it.isSuccessful) { for (document in it.result) { try { val product = document.toObject(ProductDetails::class.java) product.product_id = document.id productsList.add(product) } catch (e: Exception) { // 可自行添加日志上报逻辑 e.printStackTrace() } } } tempProductsList.addAll(productsList) listProducts() } .addOnFailureListener { it.printStackTrace() }
后续迭代兼容规范
按照以下规则新增字段,不需要每次给存量数据补字段即可正常兼容:
- 所有新增字段必须设置默认值,禁止使用无默认值的不可空类型
- 不要随意修改已有字段的命名、数据类型,如必须修改需要做双字段兼容过渡
- 所有模型类都保留
@Keep和@IgnoreExtraProperties注解
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

