如何在Flutter中遍历Firebase实时数据库的DataSnapshot
解决Firebase实时数据库InternalLinkedHashMap遍历问题
问题场景
从Firebase实时数据库读取information/hospitals节点时,返回InternalLinkedHashMap<Object?, Object?>类型数据,需要遍历提取每个子节点的lat、lng、name、phone字段,存入List<Hospitals>用于地图标记绘制,但无法正常遍历该类型数据。
已尝试的异步读取代码:
fetchMarkers() async { nHospitals.clear(); final snapshot = await dbRef.child('information/hospitals').get(); if (snapshot.exists) { print(snapshot.value); } }
已尝试的实时监听代码:
ref.onValue.listen((event) { for (final child in event.snapshot.children) { //A list of children is returned //print(child); } }, onError: (error) { //Handle the error });
Hospitals实体类代码:
import 'package:json_annotation/json_annotation.dart'; part 'hospitals.g.dart'; @JsonSerializable() class Hospitals { final String lat; final String lng; final String name; final String phone; Hospitals( {required this.lat, required this.lng, required this.name, required this.phone}); factory Hospitals.fromJson(Map<String, dynamic> json) => _$HospitalsFromJson(json); Map<String, dynamic> toJson() => _$HospitalsToJson(this); }
解决方案
方式1:异步get()读取并解析
将snapshot.value强转为Map<String, dynamic>,遍历每个键值对,通过Hospitals.fromJson将每个子节点数据转换为实体类,加入列表:
fetchMarkers() async { nHospitals.clear(); final snapshot = await dbRef.child('information/hospitals').get(); if (snapshot.exists) { // 强转类型并遍历 final hospitalsMap = snapshot.value as Map<String, dynamic>; hospitalsMap.forEach((key, value) { // 将子节点数据转为Map<String, dynamic>后解析 final hospital = Hospitals.fromJson(value as Map<String, dynamic>); nHospitals.add(hospital); }); // 此时nHospitals已填充数据,可用于地图绘制 } }
方式2:实时onValue监听并解析
遍历snapshot.children时,直接获取每个子节点的value并强转为Map<String, dynamic>,再解析为实体类:
ref.onValue.listen((event) { nHospitals.clear(); for (final child in event.snapshot.children) { // 提取子节点数据并解析 final hospitalData = child.value as Map<String, dynamic>; final hospital = Hospitals.fromJson(hospitalData); nHospitals.add(hospital); } // 更新地图标记 }, onError: (error) { // 错误处理逻辑 });
注意事项
- 确保数据库中每个
hospitals子节点的字段名与Hospitals类的属性完全匹配(比如数据库中是lng而非long,需对应实体类的lng字段)。 - 若数据库中字段值为数字类型,需修改
Hospitals类的对应属性类型为double或int,并同步fromJson/toJson方法。
内容的提问来源于stack exchange,提问作者notem101
相关产品推荐
相关产品推荐

