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

如何在向Firebase Storage上传多个文件时获取进度值?

Firebase Storage多文件上传时能否获取上传进度?

在单个文件上传到Firebase Storage时,我们可以通过监听任务的snapshotEvents事件来获取实时上传进度,示例代码如下:

uploadTask.snapshotEvents.listen((event) {
  setState(() {
    _progress =
        event.bytesTransferred.toDouble() / event.totalBytes.toDouble();
    print(_progress.toString());
  });
  if (event.state == TaskState.success) {
    _progress = null;
    Fluttertoast.showToast(msg: 'File added to the library');
  }
}).onError((error) {
  // 处理错误逻辑
});

这种方式能优化上传时的UI,实时告知用户上传状态。但在多文件上传场景中,你当前使用了await uploadTask.whenComplete()的方式来等待任务完成,示例代码如下:

Future<String> uploadFile(File file) async {
  setState(() {
    uploading = true;
    isError = false;
  });
  final storageRef = FirebaseStorage.instance.ref();
  final auth = FirebaseAuth.instance;
  final uuid = Uuid();

  Reference ref =
      storageRef.child('posts/${auth.currentUser!.email!}/${uuid.v1()}');

  final uploadTask = ref.putFile(file);

  final taskSnapshot = await uploadTask.whenComplete(() => null);
  String url = await taskSnapshot.ref.getDownloadURL();
  return url;
}

答案:可以获取上传进度

你当前的多文件上传逻辑只是用whenComplete()来等待任务结束,但这并不影响你通过监听每个uploadTask的snapshotEvents来获取对应文件的上传进度。每个文件的上传任务都是独立的,都拥有自己的进度事件流。

你可以修改uploadFile函数,添加进度监听逻辑,并通过回调来更新外部的进度状态(因为多文件需要区分每个文件的进度),示例代码如下:

Future<String> uploadFile(File file, int fileIndex, Function(int, double) updateProgress) async {
  setState(() {
    uploading = true;
    isError = false;
  });
  final storageRef = FirebaseStorage.instance.ref();
  final auth = FirebaseAuth.instance;
  final uuid = Uuid();

  Reference ref =
      storageRef.child('posts/${auth.currentUser!.email!}/${uuid.v1()}');

  final uploadTask = ref.putFile(file);

  // 监听当前文件的上传进度
  uploadTask.snapshotEvents.listen((event) {
    double progress = event.bytesTransferred.toDouble() / event.totalBytes.toDouble();
    // 通过回调更新外部维护的对应文件进度
    updateProgress(fileIndex, progress);
    
    if (event.state == TaskState.success) {
      Fluttertoast.showToast(msg: '第${fileIndex + 1}个文件上传完成');
    }
  }).onError((error) {
    setState(() {
      isError = true;
    });
    Fluttertoast.showToast(msg: '文件上传失败:${error.toString()}');
  });

  final taskSnapshot = await uploadTask.whenComplete(() => null);
  String url = await taskSnapshot.ref.getDownloadURL();
  return url;
}

使用示例

在外部维护一个存储所有文件进度的列表,然后遍历文件调用上传函数:

// 假设files是选中的文件列表
List<double> _fileProgresses = List.filled(files.length, 0.0);

for (int i = 0; i < files.length; i++) {
  uploadFile(files[i], i, (index, progress) {
    setState(() {
      _fileProgresses[index] = progress;
    });
  });
}

之后你就可以在UI层根据_fileProgresses列表展示每个文件的上传进度,也可以计算总进度(比如取所有进度的平均值,或者按文件大小加权计算)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:22:48