AngularFireStorage上传文件后始终返回undefined下载URL求助
AngularFireStorage downloadURL() 返回undefined的解决方案
刚解决了一个和你完全一样的问题——在Angular 6项目里用AngularFireStorage上传图片明明成功了,但调用downloadURL()始终返回undefined,控制台还没任何报错,折腾了好一阵终于找到原因了,分享给你:
问题重现
我的上传代码和你几乎一致:
uploadFile(e) { const file = e.target.files[0]; const filePath = `test${this.uid}`; const task = this.storage.upload(filePath, file); const dlUrl = task.downloadURL(); dlUrl.subscribe((res) => { console.log(res); // 这里一直输出undefined }); }
对应的文件选择输入框:
<input type="file" accept=".jpg,.jpeg,.png;capture=camera" (change)="uploadFile($event)">
文件确实能成功传到Firebase存储的指定路径,但就是拿不到下载链接。
临时可行方案:改用Firebase原生API
一开始我退而求其次,用Firebase原生的存储方法实现,还加了上传进度的监听,这个方法能正常返回正确的downloadURL:
import { BehaviorSubject } from 'rxjs'; percentSubject: BehaviorSubject<number> = new BehaviorSubject(0); pushUpload(file) { return new Promise((resolve, reject) => { const storageRef = firebase.storage().ref(); const uploadRef = storageRef.child(`uploads/${file.name}`); this.uploadTask = uploadRef.put(file); this.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, (snapshot: firebase.storage.UploadTaskSnapshot) => { // 实时更新上传进度 this.percentSubject.next((snapshot.bytesTransferred / snapshot.totalBytes) * 100); }, (error) => { reject(error); }, async () => { // 上传完成后获取下载链接 const downloadUrl = await this.uploadTask.snapshot.ref.getDownloadURL(); resolve(downloadUrl); } ); }); }
根源排查与最终修复
后来我去扒了AngularFire2的源码,发现问题出在版本不匹配上:angularfire2/storage模块里的task.js使用了Firebase 5.0.0已经移除的废弃API。
原task.js中的downloadURL方法:
downloadURL: function () { return from(task.then(function (s) { return s.downloadURL; // Firebase 5+已经移除了这个属性 })); }
在Firebase 5及以上版本中,snapshot.downloadURL被移除了,必须通过snapshot.ref.getDownloadURL()异步获取下载链接,所以需要把这段代码修改为:
downloadURL: function () { return from(task.then(async function (s) { return await s.ref.getDownloadURL(); })); }
修改后再调用task.downloadURL().subscribe(...)就能正常拿到下载链接了。
重要提醒:使用AngularFire2的存储功能时,一定要确保AngularFire2的版本和Firebase SDK的版本严格匹配,避免因为API废弃导致的这类隐性问题。
内容的提问来源于stack exchange,提问作者Nicholas Pesa
相关产品推荐
相关产品推荐

