Flutter如何创建读取键值对数组(Map) 实现Firestore数据存储
写入操作
Firestore 中数组类型字段的写入分两种常见场景,可根据需求选择:
- 场景1:向已有数组追加新元素(不会覆盖原有数据,首次写入时会自动创建数组字段)
你需要用 Firestore 提供的FieldValue.arrayUnion方法实现,你的setAnswer方法改造如下:
这种方式写入后,数组内每个元素都是结构相同、值不同的Map(哈希表)结构,符合你的要求。Future<void> setAnswer() async { String ans = ans_Controller.text; FirebaseFirestore db = FirebaseFirestore.instance; await db.runTransaction((transaction) async { DocumentReference qRef = db.collection('question').doc(widget.question.id); // 构造单条键值对元素,和你要求的结构一致 final newAnswer = { 'content': ans, 'timestamp': DateTime.now().toString(), 'username': _currentUser.displayName, }; await transaction.set( qRef, { // answer_records 为自定义的数组字段名,可自行修改 'answer_records': FieldValue.arrayUnion([newAnswer]) }, SetOptions(merge: true)); }); }
注意:arrayUnion会自动去重完全相同的元素,如果业务需要允许重复的相同回答,需要先读取当前数组、本地追加新元素后,再按场景2的方式全量覆盖写入。 - 场景2:直接覆盖整个数组(如果需要全量更新数组内容使用)
直接传入完整的数组即可:final allAnswers = [ {'content': '答案1', 'timestamp': 'xxx', 'username': '用户A'}, {'content': '答案2', 'timestamp': 'yyy', 'username': '用户B'} ]; await transaction.set( qRef, {'answer_records': allAnswers}, SetOptions(merge: true) );
读取操作
读取文档后直接将对应字段强转为 List<Map<String, dynamic>> 类型即可遍历使用,示例代码如下:
Future<List<Map<String, dynamic>>> getAnswerRecords(String questionId) async { FirebaseFirestore db = FirebaseFirestore.instance; DocumentSnapshot doc = await db.collection('question').doc(questionId).get(); // 取出数组字段,若字段不存在则返回空数组 final List<dynamic> rawList = doc.get('answer_records') ?? []; // 转换为Map结构的列表 return rawList.map((item) => item as Map<String, dynamic>).toList(); } // 调用示例 final answers = await getAnswerRecords(widget.question.id); // 遍历取值 for (var ans in answers) { print(ans['content']); print(ans['timestamp']); print(ans['username']); }
内容的提问来源于stack exchange,提问作者Mithson
相关产品推荐
相关产品推荐

