Проблема с загрузкой нескольких изображений firebase с прогрессом

#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();