загрузка файла в хранилище firebase с помощью angularfire - PullRequest
0 голосов
/ 16 апреля 2019

Я использую angularfire2 для загрузки изображения в хранилище Firebase. Загрузка работает очень хорошо, хотя у меня возникают проблемы с ожиданием, пока мой код для загрузки URL будет доступен. Вот код, когда файл выбирается

 async onFilesAdded(event){
      console.log("file added")
      if (event.target.files.length > 0) {
        const file = event.target.files[0];
        console.log("File name is:" + file.name)

         await this.dataSvc.pushUpload(file).then(
            (res) => {
              console.log("download url is::" + this.dataSvc.downloadURL)
            },
            (err) => console.log("fail to upload file:" + err)
          )


      }
    }

Мой сервис реализует это, как показано ниже

 pushUpload(file: File) {
    const filePath = '/' + file.name;
    const fileRef = this.storage.ref(filePath);

    return new Promise<any>((resolve, reject) => {
         const task = this.storage.upload(filePath, file);

          task.snapshotChanges().pipe(
      finalize(() => this.downloadURL = fileRef.getDownloadURL() )
   ).subscribe(
        res => resolve(res),
        err => reject(err))
   }
   )
  }

Я надеюсь подождать, пока обещание не будет выполнено, и я увижу URL-адрес загрузки. Но мой код, кажется, не ждет, и я получаю неопределенный downloadUrl, и через несколько секунд URL загрузки фактически появляется в сервисе. Так что в основном мой код, вызывающий pushUpload, не ждет окончания загрузки.

Еще один вариант, где я никогда не получаю URL загрузки внутри финализатора

pushUpload(file: File) {
    const path = '/' + file.name;
    const ref = this.storage.ref(path);

    let task = this.storage.upload(path, file);
    let snapshot   = task.snapshotChanges().pipe(
      finalize( async() =>  {
        this.downloadURL = await ref.getDownloadURL().toPromise();
        console.log("download url i got is:" + this.downloadURL)
      }),
    );
  }

1 Ответ

2 голосов
/ 18 апреля 2019

Загрузка, кажется, завершается правильно. Но вы разрешаете свое обещание первым значением, полученным из наблюдаемой snapshotChanges, у которой нет свойства downloadURL, следовательно, неопределенный результат.

Вы должны подписаться на fileRef.getDownloadURL(), чтобы получить ваш URL.

pushUpload(file: File) {
    const filePath = '/' + file.name;
    const fileRef = this.storage.ref(filePath);

    return new Promise<any>((resolve, reject) => {
        const task = this.storage.upload(filePath, file);

        task.snapshotChanges().pipe(
            finalize(() => fileRef.getDownloadURL().subscribe(
                res => resolve(res),
                err => reject(err));
            )
        ).subscribe();
    })
}

Код выглядит немного безобразно с подходом обещания. Я не знаю, можно ли подписаться внутри подписки, я никогда не делал этого раньше.

Как только наблюдаемая snapshotChanges завершает срабатывание операции finalize и подписывается на наблюдаемую fileRef.getDownloadURL(), эта наблюдаемая должна немедленно выдать URL и разрешить обещание.

И я бы порекомендовал использовать наблюдаемое вместо создания нового обещания.

...