You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Firebase实时数据库数据转图表类型不匹配异常求助

问题解决:Firebase实时数据库数据转模型的类型不匹配异常

错误原因

Firebase实时数据库返回的是键值对结构的Map(而非数组),你的模型解析代码错误地将其当作List处理,导致map方法的转换函数类型不匹配,触发'(dynamic) => ReadingModel' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>'异常。

修改方案

1. 修正模型的解析函数

更新reading_model.dart中的readingModelFromJson方法,适配Firebase返回的Map结构:

import 'dart:convert';

List<ReadingModel> readingModelFromJson(String str) {
  // 解析为Map<String, dynamic>,再提取values转为List
  Map<String, dynamic> jsonMap = json.decode(str);
  return List<ReadingModel>.from(
    jsonMap.values.map((x) => ReadingModel.fromJson(x))
  );
}

String readingModelToJson(List<ReadingModel> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class ReadingModel {
  ReadingModel(
      { required this.GPS,
        required this.MQ2,
        required this.MQ9,
        required this.Time
      });

  String GPS;
  String MQ2;
  String MQ9;
  String Time;

  factory ReadingModel.fromJson(Map<String, dynamic> json) => ReadingModel(
      GPS: json['GPS'] ?? '',
      MQ2: json['MQ2'] ?? '',
      MQ9: json['MQ9'] ?? '',
      Time: json['Time'] ?? ''
  );

  Map<String, dynamic> toJson() => {
    "GPS": GPS,
    "MQ2": MQ2,
    "MQ9": MQ9,
    "Time": Time
  };
}

注:添加了?? ''空值处理,避免字段缺失导致崩溃

2. 可选优化:处理Time字段的类型转换

如果Time字段是时间字符串(比如"12:30"),直接转int会报错,建议改为用时间戳或者调整图表的domain类型。如果是数字字符串(比如"1690000000"),可以修改模型直接存储int类型简化后续操作:

// 修改模型字段类型
int Time;

// fromJson中直接转换
Time: int.parse(json['Time'] ?? '0'),

// 图表的domainFn简化
domainFn: (ReadingModel readingModel, _) => readingModel.Time,

3. 页面代码小优化

initState里不需要嵌套setState,直接调用getData()即可:

@override
void initState() {
  getData();
  super.initState();
}

验证逻辑

修改后,getData方法会正确将Firebase返回的Map数据提取为ReadingModel列表,图表可以正常获取数据渲染。

内容的提问来源于stack exchange,提问作者Nur Haslina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:40:16