我一直在浏览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字符串作为我的变量?一旦我有了,我可以对火库更新进行排序。
答案 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
+ last
或switchMap
+ 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 ,因此建议从现在开始使用的方式。