AngularFire2 - Firebase存储getDownloadURL() - 如何返回firestore的url

6

我一直在阅读angularfire2文档,以从存储中检索downloadURL。我希望我错过了一些简单的东西。

文档说明:

@Component({
  selector: 'app-root',
  template: `<img [src]="profileUrl | async" />`
})
 export class AppComponent {
   profileUrl: Observable<string | null>;
   constructor(private storage: AngularFireStorage) {
   const ref = this.storage.ref('users/davideast.jpg');
   this.profileUrl = ref.getDownloadURL();
 }
}

然而,一旦我上传了一张图片,我希望将下载链接作为字符串返回,以便上传到Firestore。我需要这个下载链接用于外部服务。

我的函数

uploadImage(base64data) {

  const filePath = (`myURL/photo.jpg`);
  const storageRef = firebase.storage().ref();

  var metadata = {
    contentType: 'image',
    cacheControl: "public, max-age=31536000",
  };

  const ref = this.storage.ref(filePath);
  const task = ref.putString(base64data, 'data_url', metadata).then(() => {

    var downloadURL = ref.getDownloadURL();

  })

}

这会很好地上传图片。然而,我之后想把下载URL写入到Firestore。当我在控制台记录"downloadURL"变量时,我得到以下内容:

PromiseObservable {_isScalar: false, promise: y, scheduler: undefined}

下载链接在Promise Observable对象里。我该如何获取下载URL字符串并将其赋值给我的变量?一旦完成这步骤,我就可以处理Firestore的更新了。
4个回答

9
//observable to store download url
downloadURL: Observable<string>;

task.snapshotChanges().pipe(
    finalize(() => {
        this.downloadURL = fileRef.getDownloadURL();
        this.downloadURL.subscribe(url=>{this.imageUrl = url})
    })
)

参考:https://github.com/ReactiveX/rxjs/blob/master/doc/observable.md

Observable 是 RxJS 库的核心概念之一。它代表一个可观察的序列,该序列可以异步地传递零个或多个值,以及异常或完成信号。使用 Observable 可以轻松地处理异步数据流,并将其转换为可读性更高、更易于维护的代码。

最近有一些更改!(我相信是这样的..)在pipe()之后添加.subscribe()....就像.pipe(finalize(....)).subscribe(); - DHRUV GAJWA
谢谢,这对我有用,只是我把URL改成了任意。 - Md Rehan

5

嵌套订阅是一种反模式,因此不应该在 finalize 中进行订阅,而应该使用 last + switchMapconcat + defer

last + switchMap

使用last + switchMap:

task.snapshotChanges().pipe(
  last(),
  switchMap(() => fileRef.getDownloadURL())
).subscribe(url => console.log('download url:', url))

concat + defer

concat(
  task.snapshotChanges().pipe(ignoreElements()),
  defer(() => fileRef.getDownloadURL())
).subscribe(url => console.log('download url:', url))

3
自Firebase 5.0版本起,该答案不再相关,因为他们从上传任务中删除了downloadURL()函数。请参考文档

.downloadURL()可观察对象在上传完成后会发出下载URL字符串。然后您需要订阅以获取该值。
uploadImage(base64data) {

  const filePath = (`myURL/photo.jpg`);
  //const storageRef = firebase.storage().ref();

  var metadata = {
    contentType: 'image',
    cacheControl: "public, max-age=31536000",
  };

  const ref = this.storage.ref(filePath);
  const task = ref.putString(base64data, 'data_url', metadata);
  const downloadURL = task.downloadURL();

  downloadURL.subscribe(url=>{
     if(url){
         console.log(url);
         //wirte the url to firestore
     }
  })

}

希望这可以帮到你。查看此博客以获取更多详细信息:点击这里

@Hareesh,在最新版本的AngularFireStorage中,downloadURL将不再附加在任务(Task)中。 - Srinivasan K K

3

.downloadURL()不再可用,你需要使用.getDownloadURL()finalize()结合使用,如下:

.html 文件

<input type="file" (change)="uploadFile($event)">

.ts文件

import {
  AngularFireStorage,
  AngularFireStorageReference,
  AngularFireUploadTask
} from '@angular/fire/storage';
import { Component } from '@angular/core';
import { finalize } from 'rxjs/operators';

@Component({
  selector: 'app-upload',
  templateUrl: './upload.component.html',
  styleUrls: ['./upload.component.scss']
})
export class UploadComponent {
    constructor(private angularFireStorage: AngularFireStorage) {}

    public uploadFile(event: any): void {
        for (let i = 0; i < event.target.files.length; i++) {
            const file = event.target.files[i];
            const fileRef: AngularFireStorageReference = this.angularFireStorage.ref(
              file.name
            );
            const task: AngularFireUploadTask = this.angularFireStorage.upload(
              file.name,
              file
            );
            task
                .snapshotChanges()
                .pipe(
                finalize(() => {
                    fileRef.getDownloadURL().subscribe(downloadURL => {
                        console.log(downloadURL);
                    });
              })
          )
          .subscribe();
       }
   }
}  

另外,请注意@angular/fire,因为所有的AngularFire2包都正在移动到@angular/fire中,这是从现在开始使用的推荐方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接