Flutter Firebase更新数据报错:Invalid argument: Instance of 'TextEditingController'
问题原因
- 第一个报错
Unhandled Exception: Invalid argument: Instance of 'TextEditingController是因为你在调用Firestore更新接口时,直接把TextEditingController控制器对象作为值传入,Firestore无法识别该类型对象,需要读取控制器的.text属性获取输入的字符串内容。 - 第二个报错
Some requested document was not found有几个常见排查点:- 你当前的
updateAddress组件没有接收对应地址文档的ID参数,就算手动在.doc()中写死ID,也需要确认ID字符串完全匹配Firestore中对应文档的ID,不存在前后空格、拼写错误 - 确认Firestore的安全规则允许你对该文档进行更新操作
- 确认
address集合名称拼写完全正确,区分大小写
- 你当前的
修复方案
步骤1:补充组件入参
首先在updateAddress组件中新增必填的文档ID参数,从上一个跳转的页面传入对应地址的文档ID
步骤2:修正更新逻辑
修改更新按钮的点击逻辑,读取控制器的.text属性,传入正确的文档ID,添加异常捕获避免未处理报错
完整修复后代码
import 'package:flutter/services.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fluttertoast/fluttertoast.dart'; class UpdateAddress extends StatefulWidget { // 新增文档ID参数 final String docId; final String firstName; final String lastName; final String region; final String city; final String address1; final String address2; final String primaryPhone; final String secondaryPhone; const UpdateAddress( {Key? key, required this.docId, required this.firstName, required this.lastName, required this.region, required this.city, required this.address1, required this.address2, required this.primaryPhone, required this.secondaryPhone}) : super(key: key); @override _UpdateAddressState createState() => _UpdateAddressState(); } class _UpdateAddressState extends State<UpdateAddress> { late TextEditingController FirstName = TextEditingController(text: widget.firstName); late TextEditingController LastName = TextEditingController(text: widget.lastName); late TextEditingController Region = TextEditingController(text: widget.region); late TextEditingController City = TextEditingController(text: widget.city); late TextEditingController Address1 = TextEditingController(text: widget.address1); late TextEditingController Address2 = TextEditingController(text: widget.address2); late TextEditingController PrimaryPhone = TextEditingController(text: widget.primaryPhone); late TextEditingController SecondaryPhone = TextEditingController(text: widget.secondaryPhone); @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey.shade100, appBar: AppBar( centerTitle: true, backgroundColor: Theme.of(context).scaffoldBackgroundColor, title: const Text( 'Update Address', style: TextStyle(color: Colors.black), ), leading: IconButton( icon: const Icon( Icons.arrow_back_ios, color: Colors.black, ), onPressed: () { Navigator.of(context).pushNamed('/addressProfile'); }, ), ), body: Card( margin: const EdgeInsets.all(20), child: Padding( padding: const EdgeInsets.all(15), child: GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: ListView( children: [ const SizedBox( height: 30, ), TextFormField( maxLength: 20, style: const TextStyle(color: Colors.black, fontSize: 20), controller: FirstName, decoration: const InputDecoration( labelText: "First Name", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( maxLength: 20, style: const TextStyle(color: Colors.black, fontSize: 20), controller: LastName, decoration: const InputDecoration( labelText: "Last Name", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( maxLength: 15, style: const TextStyle(color: Colors.black, fontSize: 20), controller: Region, decoration: const InputDecoration( labelText: "Region", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( maxLength: 15, style: const TextStyle(color: Colors.black, fontSize: 20), controller: City, decoration: const InputDecoration( labelText: "City", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( maxLength: 20, style: const TextStyle(color: Colors.black, fontSize: 20), controller: Address1, decoration: const InputDecoration( labelText: "Address Line 1", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( maxLength: 20, style: const TextStyle(color: Colors.black, fontSize: 20), controller: Address2, decoration: const InputDecoration( labelText: "Address Line 2", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( keyboardType: TextInputType.phone, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, ], maxLength: 10, style: const TextStyle(color: Colors.black, fontSize: 20), controller: PrimaryPhone, decoration: const InputDecoration( labelText: "Primary Phone", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), TextFormField( keyboardType: TextInputType.phone, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, ], maxLength: 10, style: const TextStyle(color: Colors.black, fontSize: 20), controller: SecondaryPhone, decoration: const InputDecoration( labelText: "Secondary Phone", floatingLabelBehavior: FloatingLabelBehavior.always, ), ), const SizedBox( height: 30, ), Align( child: ElevatedButton( onPressed: () async { // 加try catch捕获异常 try { await FirebaseFirestore.instance .collection('address') // 传入正确的文档ID .doc(widget.docId) // 所有字段读取.text属性获取字符串 .update({ "firstName": FirstName.text.trim(), "lastName": LastName.text.trim(), "region": Region.text.trim(), "city": City.text.trim(), "address1": Address1.text.trim(), "address2": Address2.text.trim(), "primaryPhone": PrimaryPhone.text.trim(), "secondaryPhone": SecondaryPhone.text.trim() }); Fluttertoast.showToast( msg: "Address updated Successfully", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, textColor: Colors.black, backgroundColor: Colors.green.shade400, ); } catch (e) { Fluttertoast.showToast( msg: "Update failed: ${e.toString()}", toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.BOTTOM, textColor: Colors.white, backgroundColor: Colors.red.shade400, ); } }, child: const Text( "Update Address", style: TextStyle( fontSize: 15, letterSpacing: 2, color: Colors.black), ), style: ElevatedButton.styleFrom( fixedSize: const Size(250, 40), primary: Colors.green.shade500, padding: const EdgeInsets.symmetric( horizontal: 50, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10))), ), ) ], ), ), ), ), ); } }
额外注意
跳转进入UpdateAddress页面时,需要把对应地址文档的ID作为docId参数传入,保证和Firestore中的文档ID完全一致即可解决文档找不到的问题。
内容的提问来源于stack exchange,提问作者user17112368
相关产品推荐
相关产品推荐

