Swift中Firebase实时数据库返回数组与字典混合值问题
Firebase实时数据库解析差异:部分Chap转数组部分转字典的问题解决
问题原因
Firebase实时数据库有个隐性规则:当写入的字典键是从1开始的连续无间隙整数时,会自动把这个字典转换成数组存储。你Day 1的Chap键是"1"-"4",刚好符合这个规则,所以被转成了数组(数组索引0没有对应原键,所以是null,索引1对应原键1的值,以此类推);而其他Day的Chap键从5、9等非1开头的整数起步,不符合连续起始整数的要求,所以保持字典结构。这就导致读取时类型混乱,强制转换直接报错。
解决办法
1. 修改键命名(最彻底的方案)
给Chap的键加个前缀(比如"chap_"、"c_"),让键不再是纯连续整数,这样Firebase会始终以字典形式存储数据,从根源避免类型不一致。
修改写入代码的Chap部分:
let myDays = [ "1": ["Chap": ["chap_1":"0", "chap_2":"0", "chap_3":"0", "chap_4":"0"], "Comp": "0"], "2": ["Chap": ["chap_5":"0", "chap_6": "0", "chap_7": "0", "chap_8": "0"], "Comp": "0"], // 剩下的Day按同样规则修改键名 ]
读取时直接按字典解析:
myRef1.observe(.value, with: { snapshot in guard let chapDict = snapshot.value as? [String: String] else { // 处理解析失败的情况 return } // 后续用字典逻辑处理数据 })
2. 读取时兼容两种类型(适配已有数据)
如果已经有数据存在不想修改,可以在读取时判断数据类型,统一转换成字典格式处理:
myRef1.observe(.value, with: { snapshot in var chapDict = [String: String]() if let array = snapshot.value as? [Any?] { // 处理数组情况:索引1及以上对应原键1、2、3... for (index, value) in array.enumerated() { guard index >= 1, let strValue = value as? String else { continue } chapDict["\(index)"] = strValue } } else if let dict = snapshot.value as? [String: String] { // 直接复用字典数据 chapDict = dict } else { // 处理无法识别的类型,比如提示错误或返回空 return } // 后续统一用chapDict处理业务逻辑 print(chapDict) })
内容的提问来源于stack exchange,提问作者Douglas W. Palme
相关产品推荐
相关产品推荐

