Flutter连接Firebase更新数据时遇Bad State错误求助
解决Firestore DocumentSnapshot字段不存在错误
问题场景
开发Flutter页面,从Firebase的personal集合获取数据,按标题展示条目;点击标题进入详情页查看完整数据,详情页通过文本框和提交按钮更新该条目的response字段。运行时出现红屏错误:Bad State: field does not exist within the DocumentSnapshotPlatform。
原代码:
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class ResponsePage extends StatefulWidget { @override _ResponsePageState createState() => _ResponsePageState(); } class _ResponsePageState extends State<ResponsePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Color(0xFF006400), title: Text('Visualize Personal'), ), body: StreamBuilder( stream: FirebaseFirestore.instance.collection('personal').snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return Center( child: CircularProgressIndicator(), ); } return ListView.builder( itemCount: snapshot.data!.docs.length, itemBuilder: (context, index) { final form = snapshot.data!.docs[index]; return ListTile( title: Text(form['title']), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailPage(form: form), ), ); }, ); }, ); }, ), ); } } class DetailPage extends StatefulWidget { DetailPage({Key? key, required this.form}) : super(key: key); final DocumentSnapshot form; @override _DetailPageState createState() => _DetailPageState(); } class _DetailPageState extends State<DetailPage> { final TextEditingController _responseController = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Detail Page')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Display the data for the entry Text('Title: ${widget.form['title']}'), Text('Description: ${widget.form['description']}'), Text('Name: ${widget.form['name']}'), Text('Number: ${widget.form['number']}'), Text('Response: ${widget.form['response']}'), Text('Street: ${widget.form['street']}'), Text('Type: ${widget.form['type']}'), SizedBox(height: 16.0), // Add the text field and submit button TextField( controller: _responseController, decoration: InputDecoration( labelText: 'Response', border: OutlineInputBorder(), ), ), SizedBox(height: 8.0), ElevatedButton( child: Text('Submit'), onPressed: () { // Update the response field in the Firebase collection FirebaseFirestore.instance .collection('your_collection') .doc(widget.form.id) .update({ 'response': _responseController.text, }); Navigator.pop(context); }, ) ], ), ), ); } }
错误原因及修复方案
1. 字段不存在或拼写错误
Firestore文档中缺少代码里读取的某个字段,或者字段名拼写错误(Firestore字段名区分大小写)。比如读取widget.form['description'],但文档里实际字段是desc,或者大小写不一致(比如Description)。
修复:
- 登录Firebase控制台,检查
personal集合下的文档,确认所有读取的字段(title、description、name、number、response、street、type)都存在,且字段名完全匹配。 - 改用安全读取方式,避免字段不存在时崩溃:用
form.get('字段名', defaultValue: '无数据')替代直接form['字段名']。
2. 更新时集合名称错误
代码里更新数据时用了collection('your_collection'),但数据来自personal集合,集合名写错导致找不到文档。
修复:把your_collection改成personal。
3. 文本控制器未初始化现有值
详情页文本框默认是空的,用户看不到当前response值,体验差且易覆盖原有内容。
修复:在initState里初始化控制器,填充当前文档的response字段值。
修复后的完整代码
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class ResponsePage extends StatefulWidget { @override _ResponsePageState createState() => _ResponsePageState(); } class _ResponsePageState extends State<ResponsePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: const Color(0xFF006400), title: const Text('Visualize Personal'), ), body: StreamBuilder<QuerySnapshot>( stream: FirebaseFirestore.instance.collection('personal').snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (!snapshot.hasData || snapshot.data!.docs.isEmpty) { return const Center(child: Text('暂无数据')); } return ListView.builder( itemCount: snapshot.data!.docs.length, itemBuilder: (context, index) { final doc = snapshot.data!.docs[index]; final title = doc.get('title', defaultValue: '无标题'); return ListTile( title: Text(title), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailPage(doc: doc), ), ); }, ); }, ); }, ), ); } } class DetailPage extends StatefulWidget { const DetailPage({Key? key, required this.doc}) : super(key: key); final DocumentSnapshot doc; @override _DetailPageState createState() => _DetailPageState(); } class _DetailPageState extends State<DetailPage> { late final TextEditingController _responseController; @override void initState() { super.initState(); final currentResponse = widget.doc.get('response', defaultValue: ''); _responseController = TextEditingController(text: currentResponse.toString()); } @override void dispose() { _responseController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final title = widget.doc.get('title', defaultValue: '无数据'); final description = widget.doc.get('description', defaultValue: '无数据'); final name = widget.doc.get('name', defaultValue: '无数据'); final number = widget.doc.get('number', defaultValue: '无数据'); final response = widget.doc.get('response', defaultValue: '无数据'); final street = widget.doc.get('street', defaultValue: '无数据'); final type = widget.doc.get('type', defaultValue: '无数据'); return Scaffold( appBar: const AppBar(title: Text('Detail Page')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Title: $title'), Text('Description: $description'), Text('Name: $name'), Text('Number: $number'), Text('Response: $response'), Text('Street: $street'), Text('Type: $type'), const SizedBox(height: 16.0), TextField( controller: _responseController, decoration: const InputDecoration( labelText: 'Response', border: OutlineInputBorder(), ), ), const SizedBox(height: 8.0), ElevatedButton( onPressed: () async { await FirebaseFirestore.instance .collection('personal') .doc(widget.doc.id) .update({ 'response': _responseController.text.trim(), }); if (mounted) Navigator.pop(context); }, child: const Text('Submit'), ) ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Flank Tank
相关产品推荐
相关产品推荐

