Skip to content

Instantly share code, notes, and snippets.

Created October 3, 2016 20:30
Show Gist options
  • Save StephenFluin/6c63bb45e76629e79da08d3ac0472834 to your computer and use it in GitHub Desktop.
Save StephenFluin/6c63bb45e76629e79da08d3ac0472834 to your computer and use it in GitHub Desktop.
Firebase Uploader Component with Angular 2
import { Component, Input } from '@angular/core';
import { Router } from '@angular/router';
import { AngularFire, FirebaseListObservable } from 'angularfire2';
import { Observable } from 'rxjs';
declare var firebase: any;
interface Image {
path: string;
filename: string;
downloadURL?: string;
$key?: string;
selector: 'image-upload',
template: `
<h2>Upload a File</h2>
<form ngNoForm>
<input id="file" name="file" type="file" >
<button (click)="upload()" type="button">Upload</button>
<h2>File Gallery</h2>
<div style="overflow:hidden;">
<div *ngFor="let img of imageList | async" style="position:relative;width:100px;height:100px;float:left;display:flex;justify-content:center;align-items:center;">
<img [src]="img.downloadURL | async" style="max-width:100px;max-height:100px;">
<button (click)="delete(img)" style="position:absolute;top:2px;right:2px;">[x]</button>
export class UploadComponent {
* The name of the folder for images
* eg. posts/angular-is-awesome
@Input() folder: string;
fileList : FirebaseListObservable<Image[]>;
imageList : Observable<Image[]>;
constructor(public af: AngularFire, public router: Router) {
ngOnInit() {
ngOnChanges() {
console.log("new values for folder");
let storage =;
this.fileList =`/${this.folder}/images`);
console.log("Rendering all images in ",`/${this.folder}/images`)
this.imageList = itemList => item => {
var pathReference = storage.ref(item.path);
let result = {$key: item.$key, downloadURL: pathReference.getDownloadURL(), path: item.path, filename: item.filename};
return result;
upload() {
// Create a root reference
let storageRef =;
let success = false;
// This currently only grabs item 0, TODO refactor it to grab them all
for (let selectedFile of [(<HTMLInputElement>document.getElementById('file')).files[0]]) {
// Make local copies of services because "this" will be clobbered
let router = this.router;
let af =;
let folder = this.folder;
let path = `/${this.folder}/${}`;
var iRef = storageRef.child(path);
iRef.put(selectedFile).then((snapshot) => {
console.log('Uploaded a blob or file! Now storing the reference at',`/${this.folder}/images/`);
af.database.list(`/${folder}/images/`).push({ path: path, filename: })
delete(image: Image) {
let storagePath = image.path;
let referencePath = `${this.folder}/images/` + image.$key;
// Do these as two separate steps so you can still try delete ref if file no longer exists
// Delete from Storage
() => {},
(error) => console.error("Error deleting stored file",storagePath)
// Delete references
Copy link

Best example I've seen so far. Thanks for helping me get started with storage in ng2.

Copy link

Pretty good thanks!

Copy link

jitenagarwal19 commented Mar 26, 2017

dont you think in the line 56 something like this will work -

this.fileList.subscribe(imageRefs => {
            var that = this;
            this.imageList = [];
            if (imageRefs) {
                imageRefs.forEach(imageItem => {
                    var pathReference = storage.ref(imageItem.path);
                    (function (imageItem, pathReference) {
                        pathReference.getDownloadURL().then(url => {
                                $key: imageItem.$key,
                                downloadURL: url,
                                path: imageItem.path,
                                fileName: imageItem.fileName,
                        .catch(error => {
                            console.error('something is problem ${imageItem.fileName}');
                    })(imageItem, pathReference);


Copy link

sertrah commented Apr 3, 2017

Awesome! example but I have little doubt. how works this piece? "(/${this.folder}/images)" where from this.folder

Copy link

ghost commented Apr 6, 2017

I tried it , It is showing firebase is not defined at

Copy link

unitario commented Apr 9, 2017

Router is provided but never used. @bhawin-bigstep try and follow this implementation of initializing the app and see if it works:

Copy link

this line "[(document.getElementById('file')).files[0]]" doesn't work for me and always returning "TypeError: Cannot read property 'files' of null"

Copy link


I've been trying the "ngOnChanges" method to retrieve all the files from my firebase Storage, but increasingly it seems to be more confusing :(

Well before it happened I tried to get only one image with like this:

  **let storage =;
  var storageRef = storage.ref();
  // Create a reference to the file we want to download
  var starsRef = storageRef.child('images/IMG_0956 (1).JPG');
  // Get the download URL      
   starsRef.getDownloadURL().then(url => this.image = url  );** 

it successfully worked, but when I tried to get all the pictures using the "ngOnChanges" method which I found here, sadly I couldn't get the URL from the Item object.

here is where appear the exception:
let result = {$key: item.$key, downloadURL: pathReference.getDownloadURL(), path: item.path, filename: item.filename};//

This is the exception:

EXCEPTION: Firebase Storage: The operation 'getDownloadURL' cannot be performed on a root reference, create a non-root reference using child, such as .child('file.png').
Error: r {code: "storage/invalid-root-operation", message: "Firebase Storage: The operation 'getDownloadURL' c…", serverResponse: null, …}

Does anyone knows what is happening?


Copy link

This code is outdated now
import { AngularFire, FirebaseListObservable } from 'angularfire2'; is no longer supported in the Angularfire2 V4.0
please correct it accordingly

Copy link

magleahy commented Sep 26, 2017

You need import { Component, OnInit, OnChanges, Input } from '@angular/core'; and implements OnInit, OnChanges { for valid code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment