Flutter中使用Firebase set写入数据时的错误处理问题排查
Flutter Firestore写入行程数据报错排查
我在Flutter应用中通过Firestore的set方法写入行程数据时,错误处理逻辑失效,执行时持续报错。以下是createTrip方法和按钮触发代码,希望排查问题所在。
createTrip方法代码
Future createTrip({ required final String from, required final String to, required final String buscompany, required int price, required int seats, required DateTime date, required DateTime arrival, }) async { final tripDoc = FirebaseFirestore.instance.collection('trips').doc(); final trip = Trip( id: tripDoc.id, buscompany: buscompany, from: from, seats: seats, to: to, price: price, date: date, arrival: arrival); final json = trip.toJson(); await tripDoc.set(json).then((value) { //show trip added on dialog showDialog( context: context, builder: (_) => AlertDialog( title: const Text('Alert'), content: Text(' Trip from ${trip.from} to ${trip.to} added'), )); errorMessage = ''; }) //show error message .catchError((e) { setState(() { errorMessage = e.toString(); }); showDialog( context: context, builder: (_) => AlertDialog( title: const Text('Alert'), content: Text(' Trip not added because $errorMessage'), )); }); }
按钮触发代码
MaterialButton( onPressed: () { final buscompany = buscompanycontroller.text; final from = fromcontroller.text; final to = tocontroller.text; final price = pricecontroller.text; final seats = seatscontroller.text; final date = datecontroller.text; final arrival = arrivalcontroller.text; createTrip( from: from, to: to, buscompany: buscompany, price: int.parse(price), seats: int.parse(seats), date: DateTime.parse(date), arrival: DateTime.parse(arrival), ); }, color: kPrimaryColor, child: const Text( 'SUBMIT', style: TextStyle(color: Colors.white), ), )
问题排查及修复方案
输入解析异常未捕获:按钮触发时直接调用
int.parse和DateTime.parse,若输入为空或格式错误会直接抛出异常,且这部分异常无法被createTrip的catchError捕获(异常发生在调用createTrip之前)。
修复:在按钮onPressed中添加输入验证和异常捕获:onPressed: () { try { final buscompany = buscompanycontroller.text.trim(); final from = fromcontroller.text.trim(); final to = tocontroller.text.trim(); // 检查必填字段是否为空 if ([buscompany, from, to].any((s) => s.isEmpty)) { showDialog( context: context, builder: (_) => AlertDialog( title: const Text('提示'), content: const Text('请填写所有必填字段'), ), ); return; } final price = int.parse(pricecontroller.text.trim()); final seats = int.parse(seatscontroller.text.trim()); final date = DateTime.parse(datecontroller.text.trim()); final arrival = DateTime.parse(arrivalcontroller.text.trim()); createTrip( from: from, to: to, buscompany: buscompany, price: price, seats: seats, date: date, arrival: arrival, ); } catch (e) { showDialog( context: context, builder: (_) => AlertDialog( title: const Text('输入错误'), content: Text('格式不正确:${e.toString()}'), ), ); } },混合使用
await与then/catchError:这种写法会导致异常捕获逻辑混乱,建议统一使用try-catch,逻辑更清晰:Future createTrip({ required final String from, required final String to, required final String buscompany, required int price, required int seats, required DateTime date, required DateTime arrival, }) async { try { final tripDoc = FirebaseFirestore.instance.collection('trips').doc(); final trip = Trip( id: tripDoc.id, buscompany: buscompany, from: from, seats: seats, to: to, price: price, date: date, arrival: arrival, ); final json = trip.toJson(); await tripDoc.set(json); // 成功提示 showDialog( context: context, builder: (_) => AlertDialog( title: const Text('提示'), content: Text('从${trip.from}到${trip.to}的行程已添加'), ), ); setState(() => errorMessage = ''); } catch (e) { setState(() => errorMessage = e.toString()); // 错误提示 showDialog( context: context, builder: (_) => AlertDialog( title: const Text('提示'), content: Text('行程添加失败:$errorMessage'), ), ); } }Firestore安全规则限制:若Firestore默认拒绝所有写入操作,会导致写入失败。检查并修改安全规则,确保允许当前用户写入
trips集合:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /trips/{document} { allow write: if request.auth != null; // 允许已认证用户写入 } } }Trip.toJson格式错误:Firestore不直接支持DateTime类型,需转换为Timestamp。确保toJson方法正确处理日期字段:Map<String, dynamic> toJson() { return { 'id': id, 'buscompany': buscompany, 'from': from, 'seats': seats, 'to': to, 'price': price, 'date': Timestamp.fromDate(date), 'arrival': Timestamp.fromDate(arrival), }; }
内容的提问来源于stack exchange,提问作者godopetza
相关产品推荐
相关产品推荐

