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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:31:04