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

Flutter使用Provider无法设置从Firebase Database获取的数据如何解决

问题原因及修复方案

你遇到的类型转换错误不是ChartHistoricalData.fromJson方法的问题,是Firebase Realtime Database返回的数据结构类型和页面请求逻辑两个问题共同导致的:

  • Firebase返回的嵌套字典默认是Map<Object?, Object?>类型,你直接用as Map<String, dynamic>强转就会抛出类型不匹配的错误
  • 你把异步请求方法fetchHistoricalStockData直接写在build方法里,每次页面重绘都会触发重复请求,而且第一次build的时候请求还没完成,所以你打印的histChartData自然是空的

1. 修复Provider中的数据转换逻辑

你需要先把拿到的Object类型的map显式转换成Map<String, dynamic>,修改后的fetchHistoricalStockData方法如下:

Future<void> fetchHistoricalStockData(DatabaseReference ref) async {
  final dataSnapshot = await ref.once();
  final rawHistoricalList = dataSnapshot.value['SBIN_Historical'] as List;
  _histChartData = rawHistoricalList.map((rawItem) {
    // 先把Object?类型的map转成Map<String, dynamic>
    final itemMap = Map<String, dynamic>.from(rawItem as Map);
    return ChartHistoricalData.fromJson(itemMap);
  }).toList();
  notifyListeners();
}

2. 修复页面请求调用逻辑

不要把异步请求放在build方法里,移到initState生命周期里只执行一次:

class _ChartState extends State<SBINChart> {
  final fb = FirebaseDatabase.instance;
  late final DatabaseReference ref;

  @override
  void initState() {
    super.initState();
    ref = fb.reference();
    // 只在页面初始化的时候发起一次请求
    WidgetsBinding.instance.addPostFrameCallback((_) {
      context.read<StockProvider>().fetchHistoricalStockData(ref);
    });
  }

  @override
  Widget build(BuildContext context) {
    // 这里直接监听状态变化即可
    final histData = context.watch<StockProvider>().histChartData;
    print(histData); // 请求完成后就会拿到非空数据
    // 后续渲染逻辑可以加个判断,数据为空的时候显示加载中
    if (histData.isEmpty) {
      return const Center(child: CircularProgressIndicator());
    }
    // 你的图表渲染逻辑
    return ...;
  }
}

3. 可选优化:模型类空安全处理

你可以给fromJson方法里的数值也加个类型转换,避免Firebase返回int类型数值时报错:

ChartHistoricalData.fromJson(Map<String, dynamic> json) {
  x = DateTime.parse(json['date'] as String);
  open = (json['open'] as num).toDouble();
  high = (json['high'] as num).toDouble();
  low = (json['low'] as num).toDouble();
  close = (json['close'] as num).toDouble();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 12:33:01