为什么向Firebase写入数据时Ad类的key字段未被成功存储?
问题原因
- 参数传值错位(核心问题)
你定义的Ad数据类构造参数顺序如下:
// 顺序:user_id -> name -> button1 -> textTex -> textk -> description -> name_ads -> key data class Ad( var user_id : String? = null , var name : String? = null , var button1 : String? = null , val textTex : String? = null , val textk : String? = null , val description : String? = null, val name_ads: String?=null, val key :String? =null )
但你在fillAd()方法中是按照位置传参,没有指定参数名,传参顺序和构造顺序完全不匹配:你传入的第7个参数adsManager.db.push().key实际被赋值给了name_ads属性,而第8位的key属性没有传值,一直使用默认值null,自然无法写入数据库。
- Firebase序列化规则限制(可选触发)
如果修正参数顺序后还是没有key字段,是因为Firebase Realtime Database默认会将和节点主键重名的key属性排除序列化,避免冗余存储。
解决方案
- 修正
Ad实例化逻辑,改用命名参数传值,避免顺序错位,同时补全缺失的textTex参数:
private fun fillAd() : Ad { mBinder.apply { return Ad( user_id = user_id.text.toString(), name = name.text.toString(), button1 = button1.text.toString(), // 补全你缺失的textTex参数,按实际业务赋值 textTex = 对应控件.text.toString(), textk = textk.text.toString(), description = description.text.toString(), name_ads = name_ads.text.toString(), key = adsManager.db.push().key ) } }
- 如果需要强制把key字段写入数据库,给
Ad类的key属性加序列化标注,明确告知Firebase需要序列化该字段:
data class Ad( // 其他属性不变 @PropertyName("key") val key :String? =null )
- 修正兜底逻辑,避免数据覆盖:不要用
"empty"作为key的兜底值,否则所有key生成失败的请求都会覆盖同一个empty节点的数据,建议修改为:
fun pubilshAd(ad :Ad) { ad.key?.let { db.child(it).setValue(ad) } ?: throw IllegalArgumentException("Ad key cannot be null") }
- 修正读取数据的逻辑,你现在的读取逻辑多嵌套了两层节点查询,根本拿不到正确的Ad对象:
override fun onDataChange(snapshot : DataSnapshot) { val adArray =ArrayList<Ad>() for (item in snapshot.children){ // 直接从item获取Ad对象即可,不需要额外遍历子节点 val ad = item.getValue(Ad::class.java) ad?.let { adArray.add(it) } } readDataColbak?.readData(adArray) }
内容的提问来源于stack exchange,提问作者user16801724
相关产品推荐
相关产品推荐

