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

如何将Firebase Realtime Database数据读取并展示到Flutter应用的ListView

实现方案

1 优化现有数据存储逻辑

你当前存储数据时直接将JSON数组转为字符串存储,会增加后续读取解析的成本,建议直接存储结构化数据,修改保存按钮的onPressed逻辑如下:

onPressed: () {
  databaseRef.push().set({
    // 直接存JSON数组,不要调用toString()
    'ScannedItem': preview.barcodeItems
        .map((barCodeItem) => barCodeItem.toJson())
        .toList(),
  });
  // 保存成功后可选提示用户
  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("保存成功")));
},

2 新建扫描结果展示页面

新建一个StatefulWidget页面用于加载和展示Firebase中的数据:

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';

class ScannedResultsPage extends StatefulWidget {
  const ScannedResultsPage({super.key});

  @override
  State<ScannedResultsPage> createState() => _ScannedResultsPageState();
}

class _ScannedResultsPageState extends State<ScannedResultsPage> {
  // 初始化数据库引用
  final DatabaseReference _databaseRef = FirebaseDatabase.instance.reference().child('ScannedResults');
  // 存储解析后的扫描结果列表
  List<dynamic> _scannedResults = [];
  // 加载状态标记
  bool _isLoading = true;

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

  // 读取Firebase数据并解析
  void _loadScannedData() {
    _databaseRef.onValue.listen((event) {
      List<dynamic> tempList = [];
      // 遍历获取到的所有数据节点
      Map<dynamic, dynamic>? values = event.snapshot.value as Map?;
      if (values != null) {
        values.forEach((key, value) {
          // 把每个节点的ScannedItem数组取出添加到临时列表
          List itemList = value['ScannedItem'] as List;
          tempList.addAll(itemList);
        });
      }
      // 更新状态刷新UI
      setState(() {
        _scannedResults = tempList;
        _isLoading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("历史扫描结果")),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : _scannedResults.isEmpty
              ? const Center(child: Text("暂无扫描数据"))
              : ListView.builder(
                  itemCount: _scannedResults.length,
                  itemBuilder: (context, index) {
                    // 把Map数据转回BarcodeItem对象后传给你已有的BarcodeItemWidget
                    var barcodeItem = BarcodeItem.fromJson(_scannedResults[index]);
                    return BarcodeItemWidget(barcodeItem);
                  },
                ),
    );
  }
}

注意:上面代码中的BarcodeItem.fromJson是你需要在BarcodeItem实体类中实现的JSON反序列化方法,和你已有的toJson对应即可。

3 添加页面跳转逻辑

在你原来的BarcodesResultPreviewWidget页面添加跳转按钮,点击即可跳转到结果展示页:

// 放在你现有的Save按钮下方即可
FlatButton(
  color: Colors.blue,
  child: const Text('查看历史扫描结果'),
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const ScannedResultsPage()),
    );
  },
)

注意事项

  • 请确保你已经在项目中正确配置了Firebase Realtime Database的依赖和初始化逻辑
  • 调试阶段可以先将数据库安全规则设置为允许读写,上线前必须替换为带用户身份校验的规则
  • 如果不需要实时更新数据,可以改用once()方法只读取一次数据,减少性能消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:57:02