Vue Firebase上传图片后无法获取URL,Promise处理报错
解决
getDownloadURL()返回Promise导致的src类型错误问题 你碰到的这个问题很典型——fileData.ref.getDownloadURL()是一个异步操作,它返回的是Promise对象,而不是直接的URL字符串。你之前直接把这个Promise赋值给imageUrl,后续不管是更新数据库还是提交mutation,用的都是Promise而非实际的URL字符串,这就导致组件的src属性接收到了不符合类型要求的值,触发了那个类型检查错误。
修复方案(链式then版本)
只需要把获取下载URL的步骤拆成单独的then链,等待Promise解析出实际的URL后再执行后续操作:
createMeetup({ commit, getters }, payload) { const meetup = { title: payload.title, location: payload.location, desciption: payload.desciption, date: payload.date.toISOString(), creatorId: getters.user.id }; let imageUrl; let key; firebaseApp .database() .ref("meetups") .push(meetup) .then(data => { key = data.key; return key; }) .then(key => { const filename = payload.image.name; const ext = filename.slice(filename.lastIndexOf(".")); return firebaseApp .storage() .ref("meetups/" + key + "." + ext) .put(payload.image); }) .then(fileData => { // 先等待getDownloadURL解析出实际URL return fileData.ref.getDownloadURL(); }) .then(downloadUrl => { imageUrl = downloadUrl; // 再更新数据库中的imageUrl字段 return firebaseApp .database() .ref("meetups") .child(key) .update({ imageUrl: imageUrl }); }) .then(() => { commit("createMeetup", { ...meetup, imageUrl: imageUrl, id: key }); }) .catch(err => { console.log(err); }); },
更清晰的async/await版本
如果觉得链式then看起来有点绕,也可以把整个函数改成async函数,用await来处理异步操作,代码逻辑会更线性直观:
async createMeetup({ commit, getters }, payload) { const meetup = { title: payload.title, location: payload.location, desciption: payload.desciption, date: payload.date.toISOString(), creatorId: getters.user.id }; let imageUrl; let key; try { // 提交meetup到数据库并获取唯一key const data = await firebaseApp.database().ref("meetups").push(meetup); key = data.key; // 上传图片到存储 const filename = payload.image.name; const ext = filename.slice(filename.lastIndexOf(".")); const fileData = await firebaseApp.storage().ref(`meetups/${key}.${ext}`).put(payload.image); // 等待获取图片的下载URL imageUrl = await fileData.ref.getDownloadURL(); // 更新数据库中的imageUrl字段 await firebaseApp.database().ref("meetups").child(key).update({ imageUrl }); // 提交mutation更新本地状态 commit("createMeetup", { ...meetup, imageUrl, id: key }); } catch (err) { console.log(err); } }
不管用哪种方式,核心都是要等待getDownloadURL()的Promise完成,拿到实际的URL字符串后再使用它,这样传给组件src属性的就是符合要求的字符串,类型错误自然就解决了。
内容的提问来源于stack exchange,提问作者coderj001
相关产品推荐
相关产品推荐

