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

Flutter集成Cloud FireStore:数组数据增查及单个数据获取问题

问题描述

需要实现两个功能:

  1. 从TextEditingController中获取类似示例的列表数据结构,存入Firebase Cloud FireStore
  2. 从Firebase获取数据并在屏幕展示

目前已完成通过onPressed存储数据,也能通过get方法获取全部数据,但无法从数组类型的字段中按Key获取单个数据。

示例数据结构:

final docData = {
  "list": [
    {
      "id": "data1",
      "amount1": "2000",
    },
    {
      "id": "data2",
      "amount1": "2500",
    },
    {
      "id": "data3",
      "amount1": "3500",
    }
  ],
};

已实现的存储代码:

final db = FirebaseFirestore.instance;
db.collection("data").doc('one').set(docData).onError((e, _) => print("Error writing document: $e"));

已实现的获取代码:

final db = FirebaseFirestore.instance;
db.collection("data").orderBy('list', descending: true).get().then((QuerySnapshot snapshot) {
  snapshot.docs.forEach((element) {
    print(' ${element.data()}');
  });
});

解决方案

1. 从TextEditingController构建数据并存储

假设你有对应输入框的控制器,先收集输入值构建目标数组结构,再存入Firebase:

// 示例:定义输入控制器
final idController1 = TextEditingController(text: 'data1');
final amountController1 = TextEditingController(text: '2000');
final idController2 = TextEditingController(text: 'data2');
final amountController2 = TextEditingController(text: '2500');

// 构建数组结构
List<Map<String, String>> itemList = [
  {
    'id': idController1.text,
    'amount1': amountController1.text
  },
  {
    'id': idController2.text,
    'amount1': amountController2.text
  }
];

final docData = {'list': itemList};

// 存储到Firebase
final db = FirebaseFirestore.instance;
db.collection("data").doc('one').set(docData).onError((e, _) => print("Error writing document: $e"));

如果是动态添加输入项,可以用列表维护控制器集合,遍历生成数组。

2. 从Firebase获取数据并展示

获取数据后转为Map类型,提取数组后用ListView.builder实现UI展示:

List<Map<String, dynamic>> _itemList = [];

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

void _fetchData() {
  final db = FirebaseFirestore.instance;
  db.collection("data").doc('one').get().then((DocumentSnapshot doc) {
    if (doc.exists) {
      Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
      setState(() {
        _itemList = List.from(data['list']);
      });
    }
  });
}

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: _itemList.length,
    itemBuilder: (context, index) {
      var item = _itemList[index];
      return ListTile(
        title: Text(item['id']),
        subtitle: Text('金额:${item['amount1']}'),
      );
    },
  );
}

3. 按Key从数组中获取单个数据

如果要根据id匹配单个数据,可遍历数组查找:

// 根据id查找对应item的方法
Map<String, dynamic>? findItemById(List<Map<String, dynamic>> list, String targetId) {
  try {
    return list.firstWhere((item) => item['id'] == targetId);
  } catch (e) {
    return null;
  }
}

// 使用示例
String targetId = 'data2';
Map<String, dynamic>? targetItem = findItemById(_itemList, targetId);
if (targetItem != null) {
  print('匹配到的金额:${targetItem['amount1']}');
}

如果需要频繁按Key查询,建议调整Firebase数据结构为Map,直接通过Key取值:

// 调整后的数据结构
final docData = {
  "items": {
    "data1": {"amount1": "2000"},
    "data2": {"amount1": "2500"},
    "data3": {"amount1": "3500"}
  }
};

// 取值方式
Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
print(data['items']['data2']['amount1']); // 直接获取2500

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:33:38