How to Upload Files to Firebase Storage using Angular 4

Snippet JavaScript Angular

Last updated Apr 20, 2017

In today's lesson, I will show you how to use Angular 4 to easily upload files to Firebase Storage. Dealing with file uploads can be a developer nightmare, so using a Backend-as-a-Service (BaaS) can be a good choice to speed up development time. 

Note: This lesson is adapted from the AngularFirebase File Upload Tutorial

Lesson Checkpoints

Watch the Angular File Upload Screencast

Start by watching the file upload screencast for Angular 4 and Firebase. This will provide a high level overview of what is required to get your app up and running. 

Generate the Service with the Angular CLI

We will handle uploads in the service layer, which will allow us to bootstrap these functions into any component.  You can generate a service by running: 

ng g service uploads/shared/service

We will also need the Firebase API in the service. Here's how to import the API into the app. 

 import * as firebase from 'firebase'; 

Create an Upload Task

The upload task will handle the bulk of uploading logic. It works by using creating a promise to put the file in storage. You can then monitor the progress of this promise to retrieve a snapshot of the bytes transferred. The function will also catch the error/success state of the promise. 

@Injectable()
export class UploadService {
  constructor(private af: AngularFire, private db: AngularFireDatabase) { }

  private basePath:string = '/uploads';
  private uploadTask: firebase.storage.UploadTask;
  uploads: FirebaseListObservable;

  pushUpload(upload: Upload) {
    let storageRef = firebase.storage().ref();
    this.uploadTask = storageRef.child(`${this.basePath}/${upload.file.name}`).put(upload.file);

    this.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
      (snapshot) =>  {
        // upload in progress
        upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
      },
      (error) => {
        // upload failed
        console.log(error)
      },
      () => {
        // upload success
        upload.url = this.uploadTask.snapshot.downloadURL
        upload.name = upload.file.name
        this.saveFileData(upload)
      }
    );
  }

  // Writes the file details to the realtime db
  private saveFileData(upload: Upload) {
    this.db.list(`${this.basePath}/`).push(upload);
  }

Comments