如何实现Firebase Storage文件上传进度展示 适配同时上传双文件场景
实现Firebase Storage多文件上传进度展示方案
核心思路
你现有代码直接await task.putFile(file)会等待上传完成后才返回结果,无法获取中间上传进度。你可以通过监听上传任务的快照流事件实时计算进度,再结合双文件的业务场景,分别维护每个文件的进度或合并计算总进度即可。
步骤1:修改上传方法,支持进度回调
给原有上传方法新增进度回调参数,监听上传快照计算实时进度:
// 进度回调返回0-1的进度值,可根据需求调整为返回已上传/总字节数 Future<String?> _uploadFileToStorage(BuildContext context, File file, String path, Function(double progress)? onProgress) async { try { final ref = _firebaseStorage.ref().child(path); final uploadTask = ref.putFile(file); // 监听上传进度快照 uploadTask.snapshotEvents.listen((taskSnapshot) { if (onProgress != null) { final progress = taskSnapshot.bytesTransferred / taskSnapshot.totalBytes; onProgress(progress); } }, onError: (err) { // 可在这里处理上传异常 print(err.toString()); }); // 等待上传完成 await uploadTask; return ref.getDownloadURL(); } catch (err) { print(err.toString()); return null; } }
步骤2:管理双文件上传进度
如果是StatefulWidget场景,可在State中定义进度变量,同时启动两个上传任务并分别更新进度:
// 分别保存两个文件的上传进度,初始值为0 double _file1Progress = 0; double _file2Progress = 0; // 若需展示总进度可新增变量:double _totalProgress = 0; bool _isUploading = false; Future<void> _startBatchUpload(File file1, String savePath1, File file2, String savePath2) async { setState(() { _isUploading = true; _file1Progress = 0; _file2Progress = 0; }); // 同时触发两个上传任务 final uploadUrls = await Future.wait([ _uploadFileToStorage(context, file1, savePath1, (progress) { setState(() { _file1Progress = progress; // 如需计算总进度,可按文件大小加权计算: // _totalProgress = (_file1Progress * file1.lengthSync() + _file2Progress * file2.lengthSync()) / (file1.lengthSync() + file2.lengthSync()); }); }), _uploadFileToStorage(context, file2, savePath2, (progress) { setState(() { _file2Progress = progress; // 同理更新总进度 }); }) ]); // 上传完成后处理返回的下载链接 final file1Url = uploadUrls[0]; final file2Url = uploadUrls[1]; setState(() => _isUploading = false); }
步骤3:UI层展示进度指示器
使用Flutter自带组件或自定义组件展示进度即可:
@override Widget build(BuildContext context) { return Column( children: [ if (_isUploading) ...[ Text('文件1上传进度:${(_file1Progress * 100).toStringAsFixed(1)}%'), LinearProgressIndicator(value: _file1Progress), const SizedBox(height: 16), Text('文件2上传进度:${(_file2Progress * 100).toStringAsFixed(1)}%'), LinearProgressIndicator(value: _file2Progress), // 如需展示总进度可对应添加组件 ], // 其余业务UI ], ); }
提示:如果需要处理上传暂停、取消、失败等状态,可以在监听
snapshotEvents时判断taskSnapshot.state的枚举值,对应做UI提示即可。
内容的提问来源于stack exchange,提问作者Jovane Mullings
相关产品推荐
相关产品推荐

