Upload File to Firebase Storage with Angular 11 example

BezKoder
3 min readDec 15, 2020

In this tutorial, I will show you how to make Angular 11 File Upload Application with Firebase Storage using @angular/fire & AngularFireStorage. Files’ info will be stored in Firebase Realtime Database for Display/Delete operations.

Angular 11 File Upload Firebase Storage example

We’re gonna build an Angular 11 App that helps us:

  • upload file to Firebase Storage
  • see the progress bar with percentage
  • save file metadata (name, url) to Firebase Realtime Database
  • display list of files
  • delete any file in the list

The result in Firebase Cloud Storage:

And Realtime Database:

Data Flow

Following image shows the data flow with Angular Client, Firebase Cloud Storage & Firebase Realtime Database:

– File upload:

  • store a file to Firebase Cloud Storage
  • retrieve metadata (name, url) of the file from Firebase Cloud Storage
  • save metadata (name, url) to Firebase Realtime Database

– Display/get/delete files: use the file metadata (name, url) which is stored in Realtime Database as reference to interact with Firebase Storage.

Define File Upload Class

The FileUpload class has four fields: key, name, url, file:

export class FileUpload {
key: string;
name: string;
url: string;
file: File;
constructor(file: File) {
this.file = file;
}
}

File Upload with Firebase Storage

We need to do 2 actions:

  • upload file to Firebase Storage.
  • save file’s info (name, url) to Firebase Database.
private basePath = '/uploads';constructor(private db: AngularFireDatabase, private storage: AngularFireStorage) { }pushFileToStorage(fileUpload: FileUpload): Observable<number> {
const filePath = `${this.basePath}/${fileUpload.file.name}`;
const storageRef = this.storage.ref(filePath);
const uploadTask = this.storage.upload(filePath, fileUpload.file);
uploadTask.snapshotChanges().pipe(
finalize(() => {
storageRef.getDownloadURL().subscribe(downloadURL => {
fileUpload.url = downloadURL;
fileUpload.name = fileUpload.file.name;
this.saveFileData(fileUpload);
});
})
).subscribe();
return uploadTask.percentageChanges();
}

We use upload() method that returns an AngularFireUploadTask which provides methods for controlling and monitoring the file upload.

AngularFireUploadTask has snapshotChanges() method for emitings the raw UploadTaskSnapshot when the file upload progresses.

To get the url of the uploaded file, we use the RxJS finalize() method with getDownloadURL() which doesn’t rely on the task. So we can get notified when the download URL is available.

uploadTask.snapshotChanges().pipe(
finalize(() => this.downloadURL = fileRef.getDownloadURL() )
)
.subscribe();

Finally, we return the upload completion percentage as Observable<number> using AngularFireUploadTask‘s percentageChanges() method.

return uploadTask.percentageChanges();

Retrieve & Display List of Files from Firebase Storage

We get the list of files’info (name/url) from Firebase Realtime Database:

private basePath = '/uploads';constructor(private db: AngularFireDatabase, ...) { }getFiles(numberItems): AngularFireList<FileUpload> {
return this.db.list(this.basePath, ref =>
ref.limitToLast(numberItems));
}

With getFiles() method, we can get list of FileUploads including the key/id.

Now we’re gonna use snapshotChanges().pipe(map()) to store the key, it’s so important to use this key for removing individual item (FileUpload):

this.uploadService.getFileUploads(6).snapshotChanges().pipe(
map(changes =>
changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
)
).subscribe(fileUploads => {
this.fileUploads = fileUploads;
});

Delete File from Firebase Storage

There are 2 steps:

  • delete file’s info from Database.
  • delete file from Storage.
deleteFile(fileUpload: FileUpload): void {
this.deleteFileDatabase(fileUpload.key)
.then(() => {
this.deleteFileStorage(fileUpload.name);
})
.catch(error => console.log(error));
}
private deleteFileDatabase(key: string): void {
return this.db.list(this.basePath).remove(key);
}
private deleteFileStorage(name: string): void {
const storageRef = this.storage.ref(this.basePath);
storageRef.child(name).delete();
}

Implementation

Please visit: https://bezkoder.com/angular-11-file-upload-firebase-storage/

--

--

BezKoder

A passionate engineer in software development, especially web, mobile & cross-platform application. I love sharing knowledge by writing blogs & tutorials.