Angular 4 Firebase – Upload File to Storage

Firebase Cloud Storage helps us upload and share rich content data. Data is stored in a Google Cloud Storage bucket. With Firebase, we can perform robust operations (download/upload) regardless of network quality with strong security (Cloud Storage integrates with Firebase Authentication) and high scalability.

In this tutorial, we’re gonna look at way to upload File to Firebase Storage.

Related Post:
How to integrate Firebase with Angular 4

More Practice:
Angular 4 Firebase – Get List Files from Storage
Angular 4 Firebase – Delete File from Storage
Angular 4 Firebase – Upload Image & Display List Images from Storage

I. Technology

– Angular 4
– AngularFire2 4.0

II. How to do

1. Set up the Firebase Project & integrate Firebase with Angular 4 App

Please visit this post to know step by step.

2. Upload File Service

– define FileUpload class (name, url, file)
– create a reference to the full path of the file, including the file name
– upload data using put(file) method for local file

FileUpload class
export class FileUpload {

  $key: string;
  name: string;
  url: string;
  file: File;

  constructor(file: File) {
    this.file = file;
  }
}
Upload File Service

– create a reference to the full path of the file, including the file name
– upload data using put(file) method for local file
– monitor the Upload event using uploadTask.on() function.

import * as firebase from 'firebase';

private basePath = '/uploads';

const storageRef = firebase.storage().ref();
const uploadTask = storageRef.child(`/uploads/javasampleapproach.mp4`).put(file);

uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
      (snapshot) => {
        // in progress
        const snap = snapshot as firebase.storage.UploadTaskSnapshot
        progress.percentage = Math.round((snap.bytesTransferred / snap.totalBytes) * 100)
      },
      (error) => {
        // fail
        console.log(error)
      },
      () => {
        // success
        fileUpload.url = uploadTask.snapshot.downloadURL
        fileUpload.name = fileUpload.file.name
        this.saveFileData(fileUpload)
      }
    );

– save metadata using Firebase Realtime Database:

constructor(private db: AngularFireDatabase) {}

private saveFileData(fileUpload: FileUpload) {
  this.db.list(`uploads`).push(fileUpload);
}

III. Practice

1. Project Overview
1.1 Goal

We will build an Angular 4 Firebase App that can:
– helps user choose file from local and upload it to Firebase Storage
– show progress with percentage
– save metadata to Firebase Realtime Database

angular-4-firebase-storage-upload-file-overview

1.2 Structure

angular-4-firebase-storage-upload-file-structure

2. Step by step
2.1 Set up the Firebase Project & integrate Firebase with Angular 4 App

Please visit this post to know step by step.

angular-4-firebase-integration-copy-firebase-project-config

2.2 Add Firebase config to environments variable

Open /src/environments/environment.ts, add your Firebase configuration that we have saved when Popup window was shown:

export const environment = {
  production: false,
  firebase: {
    apiKey: 'xxx',
    authDomain: 'javasampleapproach-angular4.firebaseapp.com',
    databaseURL: 'https://javasampleapproach-angular4.firebaseio.com',
    projectId: 'javasampleapproach-angular4',
    storageBucket: 'javasampleapproach-angular4.appspot.com',
    messagingSenderId: 'xxx'
  }
};
2.3 Setup @NgModule
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';

import {AngularFireDatabaseModule} from 'angularfire2/database';
import {AngularFireModule} from 'angularfire2';

import {AppComponent} from './app.component';
import {FormUploadComponent} from './upload/form-upload/form-upload.component';
import {UploadFileService} from './upload/upload-file.service';

import {environment} from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent,
    FormUploadComponent
  ],
  imports: [
    BrowserModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireDatabaseModule
  ],
  providers: [UploadFileService],
  bootstrap: [AppComponent]
})
export class AppModule {}
2.4 Model Class
export class FileUpload {

  $key: string;
  name: string;
  url: string;
  file: File;

  constructor(file: File) {
    this.file = file;
  }
}
2.5 Service
import {Injectable} from '@angular/core';
import {AngularFireDatabase} from 'angularfire2/database';
import * as firebase from 'firebase';

import {FileUpload} from './fileupload';

@Injectable()
export class UploadFileService {

  constructor(private db: AngularFireDatabase) {}

  private basePath = '/uploads';

  pushFileToStorage(fileUpload: FileUpload, progress: {percentage: number}) {
    const storageRef = firebase.storage().ref();
    const uploadTask = storageRef.child(`${this.basePath}/${fileUpload.file.name}`).put(fileUpload.file);

    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
      (snapshot) => {
        // in progress
        const snap = snapshot as firebase.storage.UploadTaskSnapshot
        progress.percentage = Math.round((snap.bytesTransferred / snap.totalBytes) * 100)
      },
      (error) => {
        // fail
        console.log(error)
      },
      () => {
        // success
        fileUpload.url = uploadTask.snapshot.downloadURL
        fileUpload.name = fileUpload.file.name
        this.saveFileData(fileUpload)
      }
    );
  }

  private saveFileData(fileUpload: FileUpload) {
    this.db.list(`${this.basePath}/`).push(fileUpload);
  }
}
2.6 Form Upload Compoment
import {Component, OnInit} from '@angular/core';

import {UploadFileService} from '../upload-file.service';
import {FileUpload} from '../fileupload';

@Component({
  selector: 'form-upload',
  templateUrl: './form-upload.component.html',
  styleUrls: ['./form-upload.component.css']
})
export class FormUploadComponent implements OnInit {

  selectedFiles: FileList
  currentFileUpload: FileUpload
  progress: {percentage: number} = {percentage: 0}

  constructor(private uploadService: UploadFileService) {}

  ngOnInit() {
  }

  selectFile(event) {
    this.selectedFiles = event.target.files;
  }

  upload() {
    const file = this.selectedFiles.item(0)
    this.currentFileUpload = new FileUpload(file);
    this.uploadService.pushFileToStorage(this.currentFileUpload, this.progress)
  }
}

form-upload.component.html:

{{progress.percentage}}%
2.7 App Component

app.component.ts

import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'JavaSampleApproach';
  description = 'Angular4-Firebase Demo';
}

app.component.html

{{title}}

{{description}}

2.8 Check Result

Run the App, go to http://localhost:4200/.

angular-4-firebase-storage-upload-file-overview

Finish:
angular-4-firebase-storage-upload-file-result-app

Firebase Storage:
angular-4-firebase-storage-upload-file-result-storage

Firebase Database:
angular-4-firebase-storage-upload-file-result-database

IV. Source Code

Angular4FirebaseStorage



By grokonez | September 20, 2017.


Related Posts


5 thoughts on “Angular 4 Firebase – Upload File to Storage”

  1. hi awesome article,
    thanks a lot

    please guid how can prevent this error

    Firebase Storage: User does not have permission to access ‘uploads/1.png’

    thanks for your time.

    1. Hi rahul,

      Please follow this step.
      It’s important to set Database RULES .read and .write values to true.

      Best Regards,
      JSA.

      1. Hi JavaSampleApproach,

        Your tutorial is great, very well.

        I wish you can also made a sample of Forms that have field and can put an image. Just like an ID with pictures, name, address, age. etc.

        Thank you.

Got Something To Say:

Your email address will not be published. Required fields are marked *

*