Building Applications Using Angularfire2 And Deploying On Firebase

From this article, you will get Angularfire2 = Awesome SPA (single page application) at your fingertips using Angular and Firebase.

Angularfire2 is really a great library to work with Angular and Firebase. In this tutorial, I am going to show you how you can build the application using Firebase and Angular. And in the end, I will show you how you can host your application to Firebase. In short, I am going to show how you can create the application from scratch to deployment. Are you guys ready to dive in with me?? Yeah! so let’s get started...

Objective

We are going to build a simple application in which I will cover the following operations.

  • Display all products
  • Add product
  • Delete product
  • Update product
  • Upload files to Firebase storage
  • Deploy Angular application on Firebase hosting

Prerequisites

Setting up Firebase

  • First, visit the https://www.firebase.com/
  • Then, click on "See our new Website" and at the top-right corner, you will find "Go to Console". Just click on that and login to your account; else visit https://console.firebase.google.com/ and login.

  • From console, click on "Create new project".

    Angular

    Angular

Go to Authentication tab and click on Web Setup at the top-right corner to get the configuration.

Angular

Angular

Then, click on Database button to set rules for database and navigate to Rules tab and write as shown below.

Angular

Now, navigate back to Data tab and create a child under the root node which is the name of your project.

Angular

Now, click on Storage tab to enable storage of images, and create one folder, as shown below.

Angular

After creating directory inside storage, don’t forget to set its rules, by navigating to Rules tab.

Angular

So far,  we have created a Firebase project which enables the authentication using email and password, and created a database which is given both, read and write permissions, and also enabled the storage to store the photos of uploaded products. So now, we are ready to dive in.

Angular side:

  • Angular CLI should be > 1.0.6 (latest is most preferable)

    • If you don’t know how to upgrade your current cli, just follow the following steps -

      • npm uninstall –g @angular/cli (it will remove current Angular Cli)
      • npm cache clean ( It will clean the cache)
      • npm install –g @angular/cli@latest (it will install the latest cli)

    • If you don’t know how to install Angular Cli or you are new to Angular Cli, Please Follow my blog here for stp by step guide on how to install Angular Cli.

  • Now, if you are done with Angular Cli, we will create the new application.

    • ng new firebasecrudDemo (it will create new Angular application)

  • Then, navigate to the directory in which we had created the firebasecrudDemo project. Inside the firebasecrudDemo directory write the following command in your command prompt or power shell,

    • npm install firebase angularfire2 - -save (it will install angularfire2 library )

Setting app.modult.ts

Now, first of all, we need to set the web configuration (remember which I had copied from Firebase!) as shown below.

  1. export const firebaseconfig=  
  2. {  
  3.    apiKey: "",  
  4.    authDomain: "",  
  5.    databaseURL: "",  
  6.    projectId: "",  
  7.    storageBucket: "",  
  8.    messagingSenderId: ""  
  9. }   

And import it in Imports array of app.module.ts file.

  1. imports: [  
  2.     BrowserModule,  
  3.     FormsModule,  
  4.     HttpModule,    AngularFireModule.initializeApp(firebaseconfig)  
  5.   ]  

Also import the following packages to provide two services

  1. angularfireauth (which is required for user authentication and creation)
  2. angularfiredatabase (which is required for connecting with database)
    1. import { AngularFireModule } from "angularfire2";  
    2. import { AngularFireDatabase } from "angularfire2/database";  
    3.   
    4. providers: [AngularFireDatabase]  

So, our final app.module.ts will look like following.

  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3. import { FormsModule } from '@angular/forms';  
  4. import { HttpModule } from '@angular/http';  
  5.   
  6. import { AppComponent } from './app.component';  
  7. import { AngularFireModule } from "angularfire2";  
  8. import { AngularFireDatabase } from "angularfire2/database";  
  9.   
  10.   
  11. export const firebaseconfig=  
  12. {  
  13. //change with your configuration  
  14.     apiKey: "",  
  15.     authDomain: "",  
  16.     databaseURL: "",  
  17.     projectId: "",  
  18.     storageBucket: "",  
  19.     messagingSenderId: ""  
  20. }  
  21. @NgModule({  
  22.   declarations: [  
  23.     AppComponent         
  24.   ],  
  25.   imports: [  
  26.     BrowserModule,  
  27.     FormsModule,  
  28.     HttpModule,  
  29.     AngularFireModule.initializeApp(firebaseconfig)  
  30.   ],  
  31.   providers: [AngularFireDatabase],  
  32.   bootstrap: [AppComponent]  
  33. })  
  34. export class AppModule { }  

Add new Products to Database

As we had created an empty database first, we need to insert a record in the database. We are using Firebase database which is NoSQL database, so we don’t need to create table and columns and everything. We just need to create a root which we have created in previous steps and named that root to products.

Will divide this process in the following steps.

Design for add new product 
  1. <div class="row">  
  2.   <div class="container">  
  3.     <h2>Add Product</h2>  
  4.     <div class="form-group">  
  5.       <input type="text" placeholder="Enter name of the Product" class="form-control" #field >  
  6.     </div>  
  7.     <div class="form-group">  
  8.       <input type="number" placeholder="Enter price" class="form-control" #price >  
  9.     </div>  
  10.     <div class="form-group">  
  11.     <input  class="form-control"  (change)="upload(f,img)"  type="file" #f/>    
  12.     </div>  
  13.     <div class="form-group">  
  14.       <img height="100" width="100" alt="Preview Will be displayed here"  src=""  #img>  
  15.     </div>  
  16.     <button (click)="add(field,img,price)" class="btn btn-primary">Add Product</button>  
  17.   </div>  
  18. </div>  
Imports
  1. import { AngularFireDatabase, FirebaseListObservable } from "angularfire2/database";  
  2. import 'firebase/storage'  
  3. import * as firebase from 'firebase';  
  4.   
  5. constructor(public _database: AngularFireDatabase) {}  

AngularFireDatabase is required for making connection with database and it will also provide us various methods for add, update, delete, and display products.

FirebaseListObservable is used to store data which is retrieved from database.

Firebase/Storage is used to upload the images or files to Firebase storage.

Create an array of type FirebaseListObservable and upload task
  1. arr: FirebaseListObservable<any[]>;  
  2. public uploadTask: firebase.storage.UploadTask;  

Upload method (for uploading file to firebase storage)
  1. upload(f, img) {      
  2.     let storageReference = firebase.storage().ref('/images/' + f.files[0].name);  
  3.     this.uploadTask = storageReference.put(f.files[0]);  
  4.     this.uploadTask.on('state_changed'function (snapshot) {  
  5.       // Handle Progress of fileupload  
  6.     }, function (error) {  
  7.       // Handle unsuccessful uploads  
  8.     }, function () {        
  9.       // Handle successful uploads on complete  
  10.       // For instance, get the download URL: https://firebasestorage.googleapis.com/...  
  11.       storageReference.getDownloadURL().then(function (url) {  
  12.         // Insert url into an <img> tag to "download"  
  13.         img.src = url;  
  14.           
  15.       });  
  16.    
  17.     });  
  18.   }  

Here upload method has two arguments, f is a reference of input control which we had put on our html page and same img is reference of our img control.

Add method
  1. add(field,img,price) {  
  2.    this.arr.push({ pname: field.value, createdAt: new Date().toString(),price:price.value, likes: 0,image:img.src});  
  3.   
  4.   }  

So here in Add method I am using push method of array , inside the push method I am creating the object which I need to store to database. So now our root products have the following nodes

pname, createdAt, price, likes, and image. Remember, Firebase is NoSQL database, so it will store the data as tree structure. The parameter fields, img and price are the references of their corresponding html elements.

Display Products

Now, as we are done with adding a new product, it’s time to fetch the records from the database.

Html for products display
  1. <div class="row">  
  2.   <hr>  
  3. <div class="container">  
  4.  <h2>Products</h2>  
  5.   <div class="row">  
  6.     <div class="col-md-4 zweet-card" *ngFor="let item of arr | async">  
  7.       <div class="panel panel-default">  
  8.         <div class="panel-body">  
  9.           <strong>{{item.pname}}</strong> <br /> {{item.price | currency:'INR':true }}<br />  
  10.           <small>{{item.createdAt| date: 'd/M/y H.m a'}}</small>  
  11.           <img height="100" width="100" src="{{item.image}}">  
  12.           <div class="btn btn-danger btn-sm btn-remove"  (click)="remove(item.$key)">  
  13.             <i class="glyphicon glyphicon-remove"></i>  
  14.           </div>  
  15.           <div class="btn btn-info btn-sm pull-right btn-like" (click)="like(item.$key,item.likes)">  
  16.             <div class="badge badge-like-count">{{item.likes}}</div>  
  17.             <i class="glyphicon glyphicon-thumbs-up"></i>  
  18.           </div>  
  19.         </div>  
  20.       </div>  
  21.     </div>  
  22.   </div>  
  23. </div>  
  24. </div>  
Code for products display
  1. arr: FirebaseListObservable<any[]>;  
  2. ngOnInit() {  
  3.      this.arr = this._database.list('/products');  
  4.   }  

Which will fetch all the records from the database with root named as products and bind all the records to html asynchronously using that async pipe.

Delete Product

  1. remove($key) {  
  2.     this.arr.remove($key);  
  3.   }  

In Firebase when we add new record to database it will automatically generate the unique key or token which will be used to fetch the particular record uniquely . So I am using that key value to remove the particular record from database.

Update Likes for Products

  1. like($key, like) {  
  2.     this.arr.update($key, { likes: like + 1 });  
  3.   }  

This will update total like count on particular product. So here I am passing two arguments, first is that unique key and the second is to update.

Final Source Code

App.component.html

  1. <div class="row">  
  2.   <div class="container">  
  3.     <h2>Add Product</h2>  
  4.     <div class="form-group">  
  5.       <input type="text" placeholder="Enter name of the Product" class="form-control" #field >  
  6.     </div>  
  7.     <div class="form-group">  
  8.       <input type="number" placeholder="Enter price" class="form-control" #price >  
  9.     </div>  
  10.     <div class="form-group">  
  11.     <input  class="form-control"  (change)="upload(f,img)"  type="file" #f/>    
  12.     </div>  
  13.     <div class="form-group">  
  14.       <img height="100" width="100" alt="Preview Will be displayed here"  src=""  #img>  
  15.     </div>  
  16.     <button (click)="add(field,img,price)" class="btn btn-primary">Add Product</button>  
  17.   </div>  
  18. </div>  
  19. <div class="row">  
  20.   <hr>  
  21.   <div class="container">  
  22.     <h2>Products</h2>  
  23.     <div class="row">  
  24.       <div class="col-md-4 zweet-card" *ngFor="let item of arr | async">  
  25.         <div class="panel panel-default">  
  26.           <div class="panel-body">  
  27.             <strong>{{item.pname}}</strong> <br /> {{item.price | currency:'INR':true }}<br />  
  28.             <small>{{item.createdAt| date: 'd/M/y H.m a'}}</small>  
  29.             <img height="100" width="100" src="{{item.image}}">  
  30.             <div class="btn btn-danger btn-sm btn-remove" (click)="remove(item.$key)">  
  31.               <i class="glyphicon glyphicon-remove"></i>  
  32.             </div>  
  33.             <div class="btn btn-info btn-sm pull-right btn-like" (click)="like(item.$key,item.likes)">  
  34.               <div class="badge badge-like-count">{{item.likes}}</div>  
  35.               <i class="glyphicon glyphicon-thumbs-up"></i>  
  36.             </div>  
  37.           </div>  
  38.         </div>  
  39.       </div>  
  40.     </div>  
  41.   </div>  
  42. </div>  

App.component.ts

  1. import { Component,OnInit } from '@angular/core';  
  2. import { AngularFireDatabase, FirebaseListObservable } from "angularfire2/database";  
  3. import 'firebase/storage'  
  4. import * as firebase from 'firebase';  
  5. @Component({  
  6.   selector: 'app-root',  
  7.   templateUrl: './app.component.html',  
  8.   styleUrls: ['./app.component.css']  
  9. })  
  10. export class AppComponent implements OnInit {  
  11.   arr: FirebaseListObservable<any[]>;  
  12.   public uploadTask: firebase.storage.UploadTask;  
  13.   constructor(public _database: AngularFireDatabase) {}  
  14.   ngOnInit() {  
  15.      this.arr = this._database.list('/products');  
  16.   }  
  17.   add(field,img,price) {  
  18.    this.arr.push({ pname: field.value, createdAt: new Date().toString(),price:price.value, likes: 0,image:img.src});  
  19.      
  20.   }  
  21.   remove($key) {  
  22.     this.arr.remove($key);  
  23.   }  
  24.   like($key, like) {  
  25.     this.arr.update($key, { likes: like + 1 });  
  26.   }  
  27.   upload(f, img) {  
  28.       
  29.     let storageReference = firebase.storage().ref('/images/' + f.files[0].name);  
  30.     this.uploadTask = storageReference.put(f.files[0]);  
  31.     this.uploadTask.on('state_changed'function (snapshot) {  
  32.   
  33.       // Observe state change events such as progress, pause, and resume  
  34.       // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded  
  35.       var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;  
  36.       console.log('Upload is ' + progress + '% done');  
  37.         
  38.       switch (snapshot.state) {  
  39.         case firebase.storage.TaskState.PAUSED: // or 'paused'  
  40.           console.log('Upload is paused');  
  41.           break;  
  42.         case firebase.storage.TaskState.RUNNING: // or 'running'  
  43.           console.log('Upload is running');  
  44.           break;  
  45.       }  
  46.     }, function (error) {  
  47.       // Handle unsuccessful uploads  
  48.     }, function () {  
  49.         
  50.       // Handle successful uploads on complete  
  51.       // For instance, get the download URL: https://firebasestorage.googleapis.com/...  
  52.       storageReference.getDownloadURL().then(function (url) {  
  53.         // Insert url into an <img> tag to "download"  
  54.         img.src = url;  
  55.           
  56.       });  
  57.    
  58.     });  
  59.   }  
  60. }  

Isn’t it easy guys? Now we will see how to host angular application on firebase hosting. Excited? Let’s dive in to it.

Deploy Angular Application on Firebase Hosting

We had already created project on firebase using console, so now we are only required to install firebase cli. To do so navigate to your project directory in command prompt and write the following code.

npm install –g firebase-tools

Angular

Angular

firebase login

Angular

Angular

Angular

firebase init

Angular

It will ask you few questions like what features of firebase cli you want to use? In our case select hosting only using space.

Second question it will ask for project directory -- > then select the directory of your project which you have created using firebase console.

What do you want to use as your public directory? In our case the name of the public directory should be dist (which we are going to create shortly).

Configure as a single page application? Yes

Initiation is completed.

Angular

Now it is time to create build of your project which was just created.

To generate build using angular cli navigate to your project directory in command prompt and write the following code.

ng build - -prod - - aot

it will generate a build using ahead of time compilation.

Angular

Now the final step is,

firebase deploy

Angular


Angular

Conclusion

We covered a lot in this tutorial - Setting up the Firebase project, Creating Angular project, Add new product, Display product, Delete product, Deploy Angular application on Firebase Hosting and many more. I hope it will be helpful to you.

You can download the source code from here.