如何在向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
相关产品推荐
相关产品推荐

