Firebase数据转Map类型错误:如何获取数据生成折线图?
问题描述
从Firebase数据库获取数据生成折线图时,遇到类型转换错误:
'A value of type 'Object?' can't be assigned to a variable of type 'Map<dynamic, dynamic>?'
系统提示可修改变量类型,或将右侧强制转换为Map<dynamic, dynamic>?。尝试两段代码均未解决:
- 第一段给
Map<dynamic, dynamic>?类型变量赋值databaseEvent.snapshot.value时触发错误; - 第二段直接调用
dataSnapshot.value!.forEach也报错。
尝试代码1
void fetchDataFromFirebase() { final databaseReference = FirebaseDatabase.instance .ref('1TJ5Srs0JsEvXaiehwPgCkJ8Ywqsoj5ERRCVcCFhGoDA/swh'); databaseReference.once().then((DatabaseEvent databaseEvent) { if (databaseEvent.snapshot.value != null) { Map<dynamic, dynamic>? values = databaseEvent.snapshot.value; List<DataPoint> newDataPoints = []; values.forEach((key, value) { if (value['Num'] != null && value['Swh'] != null) { int? num = value['Num'] as int?; double? swh = value['Swh'] as double?; if (num != null && swh != null && num >= 1 && num <= 10) { newDataPoints.add(DataPoint(num.toDouble(), swh)); } } }); setState(() { dataPoints.clear(); dataPoints.addAll(newDataPoints); }); } }); }
尝试代码2
void fetchDataFromFirebase() { final databaseReference = FirebaseDatabase.instance .ref('1TJ5Srs0JsEvXaiehwPgCkJ8Ywqsoj5ERRCVcCFhGoDA/swh'); databaseReference.once().then((DataSnapshot dataSnapshot) { if (dataSnapshot.value != null) { List<DataPoint> newDataPoints = []; dataSnapshot.value!.forEach((key, value) { if (value['Num'] != null && value['Swh'] != null) { int? num = value['Num'] as int?; double? swh = value['Swh'] as double?; if (num != null && swh != null && num >= 1 && num <= 10) { newDataPoints.add(DataPoint(num.toDouble(), swh)); } } }); setState(() { dataPoints.clear(); dataPoints.addAll(newDataPoints); }); } }); }
解决方案
问题核心是Firebase返回的value类型为Object?,需显式做安全类型转换,同时增加类型检查避免运行时错误。修改后的代码如下:
void fetchDataFromFirebase() { final databaseReference = FirebaseDatabase.instance .ref('1TJ5Srs0JsEvXaiehwPgCkJ8Ywqsoj5ERRCVcCFhGoDA/swh'); databaseReference.once().then((DatabaseEvent databaseEvent) { final snapshotValue = databaseEvent.snapshot.value; // 先判断类型再转换,避免强制转换失败 if (snapshotValue is Map<dynamic, dynamic>) { List<DataPoint> newDataPoints = []; snapshotValue.forEach((key, value) { // 嵌套数据同样做类型检查,防止后续取值报错 if (value is Map<dynamic, dynamic>) { final num = value['Num'] as int?; final swh = value['Swh'] as double?; if (num != null && swh != null && num >= 1 && num <= 10) { newDataPoints.add(DataPoint(num.toDouble(), swh)); } } }); setState(() { dataPoints.clear(); dataPoints.addAll(newDataPoints); }); } }); }
关键修改说明:
- 类型安全检查:用
is关键字先确认snapshotValue是Map<dynamic, dynamic>类型,再进行后续操作,避免强制转换的风险; - 嵌套数据校验:遍历内部
value时,同样检查是否为Map类型,防止取['Num']和['Swh']时出现类型错误; - 修正API调用错误:第二段代码的参数类型错误,
databaseReference.once()返回的是Future<DatabaseEvent>,而非Future<DataSnapshot>,这也是其报错的原因之一。
内容的提问来源于stack exchange,提问作者Hasanmeors
相关产品推荐
相关产品推荐

