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

时间:2018-03-19 12:04:55

标签: firebase firebase-storage angularfire2

我一直在浏览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。我需要外部服务的下载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).then(() => {

    var downloadURL = ref.getDownloadURL();

  })

}

这样可以很好地上传图像。但是,我想将下载URL写入firestore。当控制台记录我的'downloadURL'变量时,我得到以下结果:

  

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

下载在promise observable中。我如何将下载URL字符串作为我的变量?一旦我有了,我可以对火库​​更新进行排序。

4 个答案:

答案 0 :(得分:5)

//可观察到存储下载网址

downloadURL:可观察;

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

答案 1 :(得分:2)

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

最后一个+ switchMap

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

concat +延迟

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

答案 2 :(得分:1)

此答案与Firebase 5.0版本无关,他们从上传任务中删除了downloadURL()。请参阅doc

上传完成后,.downloadURL() observable会发出下载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
     }
  })

}

希望这会有所帮助。查看此博客了解更多detail

答案 3 :(得分:1)

.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 ,因此建议从现在开始使用的方式。