如何从FirebaseStorageManager的uploadFile函数返回可监听的上传对象
解决方案
步骤1:修改FirebaseStorageManager的uploadFile方法
不需要在管理器内部监听进度,也不需要注入Controller,直接把创建好的UploadTask实例返回给调用方即可:
class FirebaseStorageManager { final FirebaseStorage _firebaseStorage; FirebaseStorageManager(this._firebaseStorage); Future<UploadTask?> uploadFile(XFile file, String ref) async { try { Reference fireStorageRef = _firebaseStorage.ref().child(ref); final metadata = SettableMetadata( contentType: 'image/jpeg', customMetadata: {'picked-file-path': file.path}); var _byte = await file.readAsBytes(); var uploadTask = fireStorageRef.putData(_byte, metadata); // 移除内部无用的listen和whenComplete逻辑,交给调用方处理 return uploadTask; } catch (e) { return null; } } }
步骤2:Controller侧监听上传进度
拿到UploadTask实例后,直接监听它自带的snapshotEvents流即可获取实时进度,同时可以处理完成、错误逻辑:
uploadStickerPackIcon(XFile file) async { String basename = path.basename(file.path); print('file path =${file.path}'); final uploadTask = await _firebaseStorageManager.uploadFile(file, 'pack/${basename}.jpg'); if (uploadTask == null) { // 自行添加上传初始化失败的处理逻辑 return; } // 监听上传进度流 uploadTask.snapshotEvents.listen( (event) { // 计算进度赋值给进度条变量,此处返回0-1的浮点数,需要百分比可自行乘以100 progressbarValue = event.bytesTransferred.toDouble() / event.totalBytes.toDouble(); }, onError: (e) { // 自行添加上传失败的处理逻辑 }, onDone: () async { // 上传完成后获取下载链接 final downloadUrl = await uploadTask.snapshot.ref.getDownloadURL(); // 自行添加拿到下载链接后的业务逻辑 }, ); }
报错原因说明
你之前的报错是因为直接对Future<UploadTask?>调用了asStream(),这个方法是把Future的返回值(也就是UploadTask实例本身)作为单次事件发射的Stream,监听这个流拿到的是UploadTask对象,不是你需要的TaskSnapshot进度事件,所以出现了类型不匹配的错误。
内容的提问来源于stack exchange,提问作者M.ArslanKhan
相关产品推荐
相关产品推荐

