Firebase将监听从.childAdded改为.value时获取数据触发nil解包报错怎么办
错误原因
.childAdded事件触发时,返回的snapshot对应jobposts下的单个子节点(单条招聘数据),所以你可以直接将snapshot.value转为单个[String: Any]字典,直接取title等字段是正常的。- 改为
.value事件后,返回的snapshot对应整个jobposts节点的全量数据,结构是[子节点ID: 单条招聘数据字典]的嵌套结构。你直接把全量snapshot.value转为[String: Any]后,这个字典的key是子节点的唯一ID,不是title/company这类字段,所以强制解包取字段就会拿到nil触发崩溃。你打印的dictionary输出的是所有子节点的集合,自然看不到单条数据的字段。
修复代码
你需要先遍历全量数据里的所有子节点,再逐个映射为JobData对象,同时注意.value每次返回全量数据,需要先清空原有数组避免重复:
func fetchJobs() { ref.child("jobposts").observe(.value) { (snapshot) in // 先清空原有数组,避免重复添加数据 self.jobs.removeAll() // 遍历snapshot下所有子节点(每个子节点对应一条招聘数据) for child in snapshot.children { guard let childSnapshot = child as? DataSnapshot, let dictionary = childSnapshot.value as? [String: Any], let title = dictionary["title"] as? String, let company = dictionary["company"] as? String, let city = dictionary["city"] as? String, let salary = dictionary["salary"] as? String, let creator = dictionary["creator"] as? String else { continue } var job = JobData() job.title = title job.company = company job.city = city job.salary = salary job.creator = creator self.jobs.append(job) } // 数据解析完成后可在此处添加UI刷新逻辑,比如列表刷新 } }
映射说明
需要做额外的映射处理:.value返回的是嵌套的全量集合结构,必须先拆分出单个子节点的数据,再做对象映射,同时建议把强制解包改为安全可选绑定,避免某条数据字段缺失时触发崩溃。
内容的提问来源于stack exchange,提问作者ToothFairy
相关产品推荐
相关产品推荐

