#javascript #node.js #firebase #promise #firebase-storage
#javascript #node.js #firebase #обещание #firebase-хранилище
Вопрос:
Я пытаюсь загрузить несколько изображений в firebase одновременно. Он делает это, но возвращаемый массив URL-адресов этих ссылок на облачные изображения слишком запоздал, поскольку сообщение уже отправляется с пустым массивом. Вот мой код:
// uploading media files using promises
async uploadMedia(mediaFile: string){
const extension = mediaFile.split('.')[mediaFile.split('.').length - 1];
const mediaFileName = `${Math.round(Math.random()*100000000000)}.${extension}`;
this.uploadProgress = 0;
const response = await fetch(mediaFile);
const blob = await response.blob();
const storageRef = storage.ref(`${mediaFileName}`).put(blob);
return storageRef.on(`state_changed`,snapshot=>{
this.uploadProgress = (snapshot.bytesTransferred/snapshot.totalBytes);
}, error=>{
this.error = error.message;
this.submitting = false;
this.uploadingMedia = false;
return;
},
async () => {
// check whether the media is an image or a video and add to correct arrays
if(extension == "png" || extension == "jpg"){
return storageRef.snapshot.ref.getDownloadURL().then(async (url)=>{
this.firebaseImageUrls = [...this.firebaseImageUrls, url];
return;
});
}
else{
return storageRef.snapshot.ref.getDownloadURL().then(async (url)=>{
this.firebaseVideoUrls = [...this.firebaseVideoUrls, url];
return;
});
}
});
}
Где все вызывается:
await Promise.all(this.props.store.selectedImagesArray.map(async (file:string) => {
await this.uploadMedia(file);
}))
this.submitPost(); // this submits everything with the firebaseImageUrls
любая помощь приветствуется
Ответ №1:
Проблема, похоже, в том, что storageRef.on()
не возвращает обещание. Он просто регистрирует обработчики. Я не эксперт по firebase. Возможно put(blob)
, возвращает обещание, которое вы можете использовать.
Комментарии:
1. Да, это правда. Но тогда я понятия не имею, как представить ход загрузки изображений, поскольку мне нужно ссылаться на .put(blob). Это работает, кстати, мне просто нужен статус загрузки.
Ответ №2:
Понял это. Мне пришлось дать обещание и разрешить обещание для каждой задачи загрузки, а затем выполнить цикл по всем файлам, выполняя это. Затем, когда все файлы будут полностью загружены и цикл будет завершен, я смогу отправить сообщение с файлами, которые находятся в firebaseImageUrls.
async uploadMedia(mediaFile: string){
return new Promise(async (resolve, reject) => {
//making the uploading task for one file
const extension = mediaFile.split('.')[mediaFile.split('.').length - 1];
const mediaFileName = `${Math.round(Math.random()*100000000000)}.${extension}`;
const response = await fetch(mediaFile);
const blob = await response.blob();
const storageRef = storage.ref(`${mediaFileName}`);
const task = storageRef.put(blob);
task.on(`state_changed`,snapshot=>{
this.uploadProgress = (snapshot.bytesTransferred/snapshot.totalBytes);
}, error=>{
this.error = error.message;
this.submitting = false;
this.uploadingMedia = false;
return;
},
async () => {
if(extension == "png" || extension == "jpg"){
task.snapshot.ref.getDownloadURL().then((url:any)=>{
console.log(url);
resolve(url);
});
}
else{
task.snapshot.ref.getDownloadURL().then((url:any)=>{
console.log(url);
resolve(url);
});
}
});
})
}
Цикл:
for(var i = 0; i < this.props.store.selectedImagesArray.length; i ){
const imageUrl = await this.uploadMedia(this.props.store.selectedImagesArray[i]);
this.firebaseImageUrls = [...this.firebaseImageUrls, imageUrl];
}
this.submitPost();