Skip to content

Instantly share code, notes, and snippets.

@StephenFluin
Created October 3, 2016 20:30
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • 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;
}
@Component({
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>
</form>
<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>
</div>
</div>
`,
})
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 = firebase.storage();
this.fileList = this.af.database.list(`/${this.folder}/images`);
console.log("Rendering all images in ",`/${this.folder}/images`)
this.imageList = this.fileList.map( itemList =>
itemList.map( item => {
var pathReference = storage.ref(item.path);
let result = {$key: item.$key, downloadURL: pathReference.getDownloadURL(), path: item.path, filename: item.filename};
console.log(result);
return result;
})
);
}
upload() {
// Create a root reference
let storageRef = firebase.storage().ref();
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]]) {
console.log(selectedFile);
// Make local copies of services because "this" will be clobbered
let router = this.router;
let af = this.af;
let folder = this.folder;
let path = `/${this.folder}/${selectedFile.name}`;
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: selectedFile.name })
});
}
}
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
firebase.storage().ref().child(storagePath).delete()
.then(
() => {},
(error) => console.error("Error deleting stored file",storagePath)
);
// Delete references
this.af.database.object(referencePath).remove()
}
}
@Energy4216
Copy link

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

@Rudis1261
Copy link

Pretty good thanks!

@jitenagarwal19
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 => {
                            that.imageList.push({
                                $key: imageItem.$key,
                                downloadURL: url,
                                path: imageItem.path,
                                fileName: imageItem.fileName,
                            });
                        })
                        .catch(error => {
                            console.error('something is problem ${imageItem.fileName}');
                        });
                    })(imageItem, pathReference);
                });

            }

@sertrah
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 firebase.storage()

@unitario
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: http://stackoverflow.com/questions/39067832/accessing-firebase-storage-with-angularfire2-angular2-rc-5

@MarJaysonSanAgustin
Copy link

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

@fToledo29
Copy link

Hi.

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 = firebase.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?

Thanks.

@hananurrehman
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

@magleahy
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