Firebase与Flutter web端单次读取数据为空,如何实现跨端兼容的单次查询?
问题根因
你现有代码的逻辑本身存在时序依赖问题:
resp.onChildAdded.forEach是异步监听逻辑,await resp.once()并不会等待所有onChildAdded的回调执行完成- iOS/Android端的Firebase Native SDK时序刚好让
onChildAdded的所有回调在once完成前执行完毕,所以能拿到数据;但Web端的Firebase JS SDK时序逻辑不同,once完成时onChildAdded还未全部触发,因此返回的是空列表。
跨端兼容的单次查询实现
不要使用实时事件监听做单次数据拉取,直接处理once()/get()返回的快照即可,该写法在iOS、Android、Web端完全一致:
Future<List<EspecieModel>> cargarTipoEspecie() async { final List<EspecieModel> tipoEspecie = []; Query resp = db.child('PATH/tipoespecie'); // 直接拉取一次数据,无需监听事件 final snapshot = await resp.get(); // 旧版firebase_database没有get()方法的话替换为: // final snapshot = (await resp.once()).snapshot; if (snapshot.exists) { // 遍历快照的所有子节点 final map = snapshot.value as Map<dynamic, dynamic>?; map?.forEach((key, value) { final temp = EspecieModel.fromJson(Map<String,dynamic>.from(value)); temp.idEspecie = key; tipoEspecie.add(temp); }); } print("Loaded - ${tipoEspecie.length}"); return tipoEspecie; }
额外确认项
替换代码后如果Web端还是空数据,检查两点即可:
- Web端的Firebase初始化配置和移动端保持一致
- Web端的数据库访问权限和移动端配置相同,没有跨域/权限拦截问题
现有FutureBuilder逻辑无需修改,直接替换数据拉取逻辑即可正常运行。
内容的提问来源于stack exchange,提问作者David L
相关产品推荐
相关产品推荐

