在Firebase Storage中 async/await(在上传文件后等待获取URL)



我在我的Vue项目中使用Firestore,我正在研究一个允许用户上传图像的功能,但是我面临以下问题:

我有一个'newMarker'占位符对象,用户用信息填充它,一旦用户确认输入,对象就被保存到数据库中。当用户确认输入时,我想:

  1. 将图像保存在Firebase Storage
  2. 获取文件生成的URL
  3. 将URL添加到newMarker对象
  4. ,然后将包含imgURL的newMarker对象推送到数据库

然而,我无法弄清楚如何使代码等待回调函数,运行一旦上传状态完成(在uploadIMG函数,'uploadTask.on(firebase.storage.TaskEvent. on)。STATE_CHANGED',最后一个回调函数),并返回一个带有url的承诺。无论我做什么,这个回调函数都是最后执行的。

当用户确认输入时,将执行saveNewMarker(),并运行以下代码:

我代码:

async saveNewMarker() {
await this.uploadImg();
console.log('Image upload finished! Pushing new marker to db')
await db.collection(this.user.email).add({
position: this.newMarker.position,
type: this.newMarker.type,
location: this.newMarker.location,
imgURL: this.newMarker.imgURL
})
.then((marker) => {
console.log('marker added to database')
this.newMarker.id = marker.id
})
},
async uploadImg(){
console.log('Uploading image ...')
const storageRef = firebase.storage().ref();
const uploadTask = storageRef.child('user-uploads/images/' + this.file.name).put(this.name)
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, 
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
}, 
(error) => {
console.log(error)
}, 
async () => {
const imgURL = await uploadTask.snapshot.ref.getDownloadURL()
console.log('uploaded image: ' + imgURL)
this.newMarker.imgURL = imgURL
}
);
},

输出:

Uploading image ...
Upload is NaN% done
Image upload finished! Pushing new marker to db
marker added to database
uploaded image: https://firebasestorage.googleapis.com/v0/b/....

预期输出:

Uploading image ...
Upload is NaN% done
uploaded image: https://firebasestorage.googleapis.com/v0/b/....
Image upload finished! Pushing new marker to db
marker added to database

这不是async/await的使用方式,我建议使用Promises代替,像这样:

function saveNewMarker() {
// Call uploadImg as a Promise and wait for the result
this.uploadImg()
.then((imgURL) => {
console.log('Image upload finished! Pushing new marker to db');
db.collection(this.user.email).add({
position: this.newMarker.position,
type: this.newMarker.type,
location: this.newMarker.location,
imgURL: this.newMarker.imgURL
})
.then((marker) => {
console.log('marker added to database');
this.newMarker.id = marker.id;
})
}).catch((error) => {
//Do something
});
};
function uploadImg() {
// Return a promise that will either resolve or emit an error
return new Promise((resolve, reject) => {
console.log('Uploading image ...');
const storageRef = firebase.storage().ref();
const uploadTask = storageRef.child('user-uploads/images/' + this.file.name).put(this.name);
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
},
(error) => {
console.log(error);
// An error occurred so inform the caller
reject(error);
},
async () => {
const imgURL = await uploadTask.snapshot.ref.getDownloadURL();
console.log('uploaded image: ' + imgURL);
this.newMarker.imgURL = imgURL;
// We 'awaited' the imgURL, now resolve this Promise
resolve(imgURL);
}
);
});
};

并记住分号,以避免意外的行为或错误。

您将不得不在承诺中包装uploadImg中的代码,并在图像上传完成后解决它。将uploadImg重构为如下所示:

async uploadImg() {
return new Promise((resolve, reject) => {
console.log("Uploading image ...");
const storageRef = firebase.storage().ref();
const uploadTask = storageRef.child("user-uploads/images/" + this.file.name).put(this.name);
uploadTask.on(
firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
},
(error) => {
console.log(error);
reject(error);
},
async () => {
const imgURL = await uploadTask.snapshot.ref.getDownloadURL();
console.log("uploaded image: " + imgURL);
this.newMarker.imgURL = imgURL;
resolve();
}
);
});
},

最新更新