Firestore Kotlin数据类@set:Exclude不生效,无法排除字段写入
解决Firestore写入时排除字段的问题
我之前也踩过Firestore这个注解的坑!你遇到的问题其实是Kotlin注解目标和Firestore序列化逻辑不匹配导致的,咱们一步步解决:
1. 用@field:Exclude替代普通@Exclude
在Kotlin中,直接写@Exclude默认是作用于属性(property),而Firestore在处理写入操作时,需要注解直接作用于**字段(field)**才会生效。改成下面的写法:
@field:Exclude var uId: String = ""
这个注解会让Firestore在写入和读取数据时都忽略该字段,完美解决你写入时字段无法排除的问题。
2. 若需细粒度控制(写入排除,读取保留)
如果你只想在写入时排除uId,但读取数据时仍要保留这个字段,可以用两种方式:
方式一:手动构建写入用的Map
直接跳过uId字段构建数据Map,虽然繁琐但直观:
// 假设你的User类有name、email、uId等字段 val writeData = mapOf( "name" to user.name, "email" to user.email, // 只包含需要写入的字段,不加入uId ) FirebaseFirestore.getInstance() .collection("users") .document() .set(writeData)
方式二:自定义Firestore转换器
写一个转换器,在序列化到Firestore时移除指定字段:
class UserConverter : FirebaseFirestoreConverter<User> { override fun toFirestore(model: User): Map<String, Any> { // 把对象转成Map后移除uId return model.toMap().apply { remove("uId") } } override fun fromFirestore(snapshot: DocumentSnapshot, options: SnapshotOptions): User { // 读取时正常转回对象,保留uId return snapshot.toObject(User::class.java) ?: User() } }
然后注册这个转换器(全局或单个集合):
// 全局注册,对所有User类操作生效 FirebaseFirestore.getInstance().setFirestoreSettings( FirebaseFirestoreSettings.Builder() .setConverter(UserConverter()) .build() ) // 或者单个集合注册 val usersRef = FirebaseFirestore.getInstance().collection("users") usersRef.setConverter(UserConverter())
为什么之前的写法无效?
- 普通
@Exclude:Kotlin默认作用于property,Firestore写入时未识别到字段级的排除指令; @set:Exclude:只作用于setter方法,Firestore写入时是直接序列化字段,而非调用setter,所以不生效;@get:Exclude:仅作用于getter方法,所以只有读取数据时会排除字段。
内容的提问来源于stack exchange,提问作者Ashraf Patel
相关产品推荐
相关产品推荐

