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
相关产品推荐
相关产品推荐

