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

如何在Firebase的CRUD操作中正确捕获错误?断网场景异常排查

问题分析与修复方案

核心问题

  1. Firebase Storage断网时不会立即抛出错误:putFile默认自带重试逻辑,断网后会持续尝试上传,不会触发catch块,导致加载器一直处于激活状态。
  2. 云函数调用的异常未被捕获:updateJobColumn的.then()未绑定错误处理,这里的异常会直接逃逸,无法触发错误提示。
  3. 加载状态重置逻辑冗余:函数末尾无条件设置_isLoading = false,可能干扰异常场景下的状态控制。

修复步骤

1. 给Storage上传添加超时/取消机制

修改putFile调用,添加超时配置,超时后主动取消任务并抛出错误:

_uploadImages(context) async {
  setState(() {
    _isLoading = true;
  });
  try {
    List filesList = [];
    var imgCount = await _getImageCountPerJob();
    for (var photo in _imageFileList!) {
      final destination = 'job-images/$jobId/img/img_$imgCount';
      imgCount++;
      final ref = FirebaseStorage.instance.ref(destination);
      var file = File(photo.path);
      // 创建上传任务并设置超时
      UploadTask uploadTask = ref.putFile(file);
      await uploadTask.timeout(const Duration(seconds: 10)).catchError((error) {
        uploadTask.cancel();
        throw error;
      });
      var imageUrl = await ref.getDownloadURL();
      filesList.add(imageUrl);
    }
    // ...后续代码

2. 统一捕获所有异常

将updateJobColumn的.then()改为await,让异常能被外层try/catch捕获:

// 替换then为await,确保异常进入外层catch
await _cloudFunctions.updateJobColumn(
  documentId: jobId,
  fieldNameColumn: jobImagesListColumnt,
  fieldNameColumnValue: filesList,
);
_displaySnackBarMessage("Success uploading images", context);
setState(() {
  _imageFileList = [];
  _isLoading = false;
});

3. 调整加载状态逻辑

移除函数末尾无条件的setState,只在成功完成或捕获到异常时修改状态:

_uploadImages(context) async {
  setState(() {
    _isLoading = true;
  });
  try {
    // ...上传和云函数调用逻辑
    setState(() {
      _imageFileList = [];
      _isLoading = false;
    });
  } catch (err) {
    log('上传错误: $err');
    _displaySnackBarMessage("Error uploading images", context);
    setState(() {
      _isLoading = false;
    });
  }
}

4. 可选:监听网络状态

引入connectivity_plus包,在上传前检查网络状态,无网络时直接抛出错误:

import 'package:connectivity_plus/connectivity_plus.dart';

// 在上传逻辑开头添加
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
  throw Exception("无网络连接,请检查网络设置");
}

额外说明

  • Firebase Storage的重试机制是为了提升上传成功率,但在需要即时反馈的场景下,必须手动限制超时或监听网络状态。
  • 使用await替代.then()能让异步代码逻辑更线性,异常捕获更可靠。

内容的提问来源于stack exchange,提问作者user17281101

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:20:45