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

Firebase DataSnapshot.getValue()未文档化异常行为求助

问题原因与解决方案

代码示例

assertEquals(mapOf("161" to "a", "163" to "b"), Firebase.database.getReference("case").get().await().value)
assertEquals(mapOf("1" to "hello", "3" to "hi"), Firebase.database.getReference("case2").get().await().value)

断言错误信息

java.lang.AssertionError: expected:<{1=hello, 3=hi}> but was:<[null, hello, null, hi]>

数据库情况

case节点使用非连续的大数字键(161、163),case2节点使用了0-3范围内的数字键(仅1、3有值,0、2无数据)。


原因

Firebase Realtime Database有自动解析规则:当节点的键是从0开始的连续整数范围时,会自动将节点解析为数组(List),缺失的索引位置填充为null;只有当键是非连续整数或非数字字符串时,才会解析为Map。

case2的键1、3落在0-3的连续整数区间内,因此被解析成数组[null, hello, null, hi],和你预期的Map结构不匹配,导致断言失败。而case的键161、163不在连续小整数范围内,所以正常解析为Map。

解决方法

方法1:修改数据库键格式

给数字键添加字符串前缀(比如key_1、key_3),让Firebase将其识别为字符串键,这样读取时会直接返回Map:

// 数据库中case2的键改为key_1、key_3后,断言可改为:
assertEquals(mapOf("key_1" to "hello", "key_3" to "hi"), Firebase.database.getReference("case2").get().await().value)

方法2:手动将数组转换为Map

如果不想修改数据库结构,可以在读取数据后,将数组转换为过滤掉null值的Map:

val case2Snapshot = Firebase.database.getReference("case2").get().await()
val case2Map = (case2Snapshot.value as List<*>).mapIndexedNotNull { index, value ->
    value?.let { index.toString() to it }
}.toMap()
assertEquals(mapOf("1" to "hello", "3" to "hi"), case2Map)

内容的提问来源于stack exchange,提问作者nbransby

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:46:12