SwiftUI调用Firebase的ref.child()查询返回整个顶层集合问题
问题原因
你遇到的是Firebase Realtime Database Apple SDK旧版本的已知问题,触发条件和逻辑如下:
- 当你对
users/父路径添加.childAdded活跃监听器时,SDK会自动拉取该路径下的所有全量数据存储到本地缓存 - 如果你项目中开启了数据库磁盘持久化配置(
Database.database().isPersistenceEnabled = true),在6.32.0之前的SDK版本中,子路径的getData调用会错误读取父路径的全量缓存数据返回,不管你传入的子路径参数是什么,都会拿到整个users节点的内容。 - 空白项目运行正常是因为默认没有开启磁盘持久化,或者空白项目集成的SDK版本更高,已经修复了该问题。
解决方案
1. 升级SDK(优先推荐)
直接升级Firebase Database SDK到最新正式版即可解决该bug。修改Podfile中Firebase/Database的版本约束后,执行以下命令升级:
pod update Firebase/Database
2. 调整监听器逻辑
如果暂时无法升级SDK,可以通过调整代码逻辑规避问题:
- 不需要监听
users节点的新增事件时,及时移除监听器:observe方法会返回一个DatabaseHandle类型的标识,存储该标识后调用ref.removeObserver(withHandle: 存储的handle)即可移除监听器,释放父路径的缓存关联。 - 如果你确实需要同时监听
users节点的新增事件和子节点数据,可以直接从第一个监听器返回的snapshot中提取对应子节点的数据,不需要额外调用getData发起请求,既规避问题也减少不必要的网络开销。
3. 临时替代方案
如果前两种方案都不适用,可以用observeSingleEvent替代getData,该方法在旧版本SDK中的缓存处理逻辑更稳定,不会出现返回全量父节点数据的问题,替换代码如下:
drivingTowardsRef.observe(.childAdded) { snapshot in ref.child(snapshot.key).observeSingleEvent(of: .value) { userSnapshot in print("Got arriving user data \(snapshot.key): \(String(describing: userSnapshot.value))") } withCancel: { error in print(error) } }
内容的提问来源于stack exchange,提问作者L_Cleo
相关产品推荐
相关产品推荐

