AngularFire2 - Firebase storage getDownloadURL() - How to return the url for firestore
Solution 1
This answer is not relevant from Firebase 5.0 release, they removed downloadURL() from upload task. Please refer to doc.
The .downloadURL()
observable emits the download URL string once the upload is completed. Then you need to subscribe to get the value.
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
}
})
}
Hope this helps. check this blog for more detail
Solution 2
//observable to store download url
downloadURL: Observable<string>;
task.snapshotChanges().pipe(
finalize(() => {
this.downloadURL = fileRef.getDownloadURL();
this.downloadURL.subscribe(url=>{this.imageUrl = url})
})
)
refer :https://github.com/ReactiveX/rxjs/blob/master/doc/observable.md
Solution 3
Nesting subscriptions is an antipattern so instead of subscribing in finalize
you should use last
+ switchMap
or concat
+ defer
.
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))
Solution 4
.downloadURL()
doesn't works longer anymore, you need to use .getDownloadURL()
combined with finalize()
like so:
.html file
<input type="file" (change)="uploadFile($event)">
.ts file
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();
}
}
}
Also, note the @angular/fire, it's because all AngularFire2 package is moving into @angular/fire and this is the recommended way to use from now onwards.
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 12, 2022Comments
-
Admin about 2 years
I've been going through the angularfire2 documentation to retrieve a downloadURl from storage. I'm hoping I'm missing something simple here.
The documentation states:
@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(); } }
However, once I've uploaded an image I want to return the download url as a string to upload to firestore. I need the download URL for an external service.
My function
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(); }) }
This uploads the image perfectly fine. However, I would then like to write the download URL to firestore. When console logging my 'downloadURL' variable, I get the following:
PromiseObservable {_isScalar: false, promise: y, scheduler: undefined}
The download is inside the promise observable. How do I just get the download URL string as my variable? Once I have that I can sort the firestore updates out.
-
Srinivasan K K about 6 years@Hareesh downloadURL will no longer be attached with Task in recent release of AngularFireStorage.
-
DHRUV GAJWA almost 5 yearsThere are some changes brought recently! (I believe so..) Add *** .subscribe() ** after pipe() .... like ... .pipe(finalize(....)).subscribe();
-
Md Rehan over 2 yearsthanks this works for me only I changed to url: any