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

Flutter中如何正确建模Firebase Realtime Database数据并使用?

问题:使用Model类解析Firebase数据后ListView无法显示内容

当前应用前后端代码混写,尝试分离前后端时,使用TestModel解析Firebase数据后,ListView显示为空,打印变量仅返回instance of TestModel,但不使用Model时能正常展示数据。

现有代码情况

TestModel类

class TestModel with ChangeNotifier {
  String? img;
  String? path;
  String? title;

  TestModel({required this.img, required this.path, required this.title});

  factory TestModel.fromJson(Map<dynamic, dynamic> json) {
    return TestModel(
        img: json['img'], path: json['path'], title: json['title']);
  }
}

未使用Model时的正常数据获取代码

Future<void> getCategory() async {
  var nameObect = await _dbRef.child('CategoryMenu').get();
  if (nameObect.exists) {
    var see = nameObect.value as Map;
    see.entries.map((e) => categoryMenuList.add(e.value)).toList();
    setState(() {});
  } else {
    print('Fail');
  }
}

修改后(使用Model但异常)的代码

Future<void> getCategory() async {
  var nameObject = await _dbRef.child('CategoryMenu').get();
  if (nameObject.exists) {
    var test = nameObject.value as Map<dynamic, dynamic>;
    TestModel category = TestModel.fromJson(test);
    modelList.add(category);
    setState(() {});
  }
}

ListView展示代码

ListView.separated(
  itemCount: modelList.length,
  itemBuilder: (context, index) {
    final catItem = modelList[index];
    String catIgm = catItem.img.toString();
    String title = catItem.title.toString();
    String path = catItem.path.toString();
    return SizedBox(
      width: 95,
      height: 100,
      child: Text(title)
    );
  }),

解决方法

1. 修正数据解析逻辑(核心问题)

问题根源:nameObject.value是一个包含多个Category节点的Map(key为节点ID,value为单个Category的Map数据),你之前直接把整个大Map传给TestModel.fromJson,导致解析出的对象并非有效Category。需要遍历每个entry,逐个转换为TestModel:

修改后的getCategory方法:

Future<void> getCategory() async {
  var nameObject = await _dbRef.child('CategoryMenu').get();
  if (nameObject.exists) {
    var test = nameObject.value as Map<dynamic, dynamic>;
    // 遍历每个Category节点,转换为TestModel并添加到列表
    test.entries.forEach((entry) {
      // entry.value才是单个Category的Map数据
      TestModel category = TestModel.fromJson(entry.value);
      modelList.add(category);
    });
    setState(() {});
  } else {
    print('Fail');
  }
}

2. 添加toString方法方便调试

给TestModel添加toString方法,这样打印对象时能看到具体字段值,便于排查问题:

class TestModel with ChangeNotifier {
  String? img;
  String? path;
  String? title;

  TestModel({required this.img, required this.path, required this.title});

  factory TestModel.fromJson(Map<dynamic, dynamic> json) {
    return TestModel(
        img: json['img'], path: json['path'], title: json['title']);
  }

  // 添加toString方法
  @override
  String toString() {
    return 'TestModel(img: $img, path: $path, title: $title)';
  }
}

3. 优化ListView的空值处理

避免字段为null时toString()显示"null"字符串,可做空值判断,同时补充缺失的separatorBuilder避免报错:

ListView.separated(
  itemCount: modelList.length,
  separatorBuilder: (context, index) => const SizedBox(width: 10),
  itemBuilder: (context, index) {
    final catItem = modelList[index];
    // 空值处理,默认显示占位文本
    String title = catItem.title ?? '无标题';
    String catImg = catItem.img ?? '';
    String path = catItem.path ?? '';
    return SizedBox(
      width: 95,
      height: 100,
      child: Text(title),
    );
  },
),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:25:23