Reasons to use Ionic Framework and Firebase

Ionic is a free and open source framework which allows you to build mobile apps easily using web technologies. The good news is that if you already know how to build websites, then you know how to build mobile apps. Ionic Framework offers the best web and native app components for building highly interactive, native and progressive web apps.

You can think of Ionic as the front-end UI framework that handles all of the look and feel and UI interactions your app needs in order to be compelling. It's like a kind of "Bootstrap for Native" but with all the support for a broad range of common native mobile components, slick animations, and incredible design.

Also, it allows developers to design apps for every app store and mobile web, using a unique base code.

If you want to learn more about Ionic I deeply suggest you to read our Ionic Tutorial: Building a complete mobile app with Ionic 3. to learn Ionic from from scratch for free!

Firebase is a popular tool that helps you build apps fast, without managing infrastructure. It’s a powerful Database as a Service (DBaaS) solution which provides a scalable NoSQL cloud database to store and sync data for client and server side development. Firebase is built on Google infrastructure and scales automatically, for even the largest apps, so you don’t need to worry about scaling your own servers.

Is Firebase Free?

Firebase has a freemium model and is not open source, however, you can use it for free if you don't pass the limits of their free tier. So if you plan to build a big application with lots of users check their pricing page before deciding to use it. Depending on your needs, you may be fine with the Free tier.

Support for Firebase in Ionic and Angular has been growing recently, and in this firebase ionic 3 tutorial, we will show you how to create an ionic and firebase example app that is able to perform the CRUD operations using Firebase as a database and also as a file storage.

At IonicThemes we firmly believe that learning to code is much easier with practical examples. That's why in all our ionic framework tutorials we always create and deliver a FREE and fully functional Ionic example application.

Ionic and Firebase Starter App

Clicking the GET THE CODE button from above, you’ll be able to download the ionic firebase example app that we developed for this ionic tutorial. This app has a basic login with email and password implemented with Firebase and a list of tasks on which we’ll perform CRUD operations such as create, read, update and delete a task.

We will go through the step by step of building a To Do App with Ionic and Firebase. Feel free to reuse this starter app as a boilerplate to start building your own Ionic Framework mobile application.

Our Firebase database will have a collection of Tasks and each Task will have the following attributes:

  • Title
  • Description
  • Image (to be stored in firebase storage)

It’s important to emphasize that the tasks will be associated to the logged in user, that’s why we need to implement authentication.

To learn more about firebase authentication, read Firebase Authentication in Ionic Framework Apps.

In this ionic 3 firebase guide you will learn the following:

  1. How to create an Ionic application and install the required dependencies
  2. How to create a firebase application
  3. How to connect the ionic app with the firebase app
  4. How to perform a simple login with firebase from an Ionic app
  5. How to write the Ionic code for the CRUD operations
  6. How to upload an image from an ionic app to firebase storage

Creating the Ionic Framework application

To begin with this guide, we’re going to create an application with Ionic Framework. You can download this example for free (clicking the Get The Code button from above) or you can create your own ionic app from scratch.

This is the Application that we’re going to build in this Ionic tutorial:

To communicate our ionic application to the firebase project we’ll use the angularfire2 plugin.

I'll show you how to create the Firebase project in the next step. To install AngularFire we need to run the following command from our console:

npm install firebase angularfire2 --save

We’ll also have to install the Image Picker plugin in our Ionic app. We’re going to use this plugin so that our Ionic app can access our cell phone’s image gallery and thus be able to create tasks with images that we can then store in the Firebase Storage.

To install the Image picker plugin, we’ll run the following commands in our console:

ionic cordova plugin add cordova-plugin-telerik-imagepicker --variable PHOTO_LIBRARY_USAGE_DESCRIPTION="your usage message"

npm install --save @ionic-native/image-picker

If you want to learn more about handling images in Firebase I recommend reading How to upload an image to Firebase from an Ionic app? and if you want to learn about image management in general within an Ionic Framework application I recommend Image handling in an Ionic 3 app.

Creating the Firebase Application

Once AngularFire has been installed (the plugin that we’ll use to communicate our Ionic app with Firebase), we need to create a new project in Firebase. To create a project, go to the firebase console, where you’ll see the following menu:

Click on "Add Firebase to your web app" to see your new Firebase application’s credentials. We’ll specify these credentials to tell our Ionic application to communicate with our Firebase application.

The next step will be to add our Firebase credentials to our Ionic application. For this we’ll go to our Ionic project, which we created in the previous step, and add the following code in the environment.ts file located in src/environments/:

export const environment = {
 production: false,
 firebase: {
   apiKey: "YOUR_API_KEY",
   authDomain: "YOUR_AUTH_DOMAIN",
   databaseURL: "YOUR_DATABASE_URL",
   projectId: "YOUR_PROJECT_ID",
   storageBucket: "YOUR_STORAGE_BUCKET",
   messagingSenderId: "YOUR_SENDER_ID"
 }
};

Keep in mind that you have to replace the constants with your own values.

Now we’re ready to start implementing the CRUD with Firebase and Ionic.

Building a CRUD app with Ionic and Firebase

To implement the CRUD functionalities, we created two services: auth.service.ts where we have everything related to authentication and firebase.service.ts where we have everything related to the CRUD logic.

Firebase Authentication

We’ll start with the authentication service methods, where we’ll have the login, register and logout. We opted to implement a simple authentication so that each user can have his or her own tasks. In other words, each task belongs only to the user who created it.

Before going to the technical part, I want to mention that we have another guide where we explain step by step how to add social logins using firebase to an Ionic framework mobile application. Also, in the authentication tutorial we explain the benefits of adding social authentication providers to your ionic app, and also explore every possible option to implement it.

So, let's see how to perform Log In and Register functionalities to get a user authenticated with firebase email and password. It's very simple, we just need to import the Firebase library (which was installed with angularfire2) and call the createUserWithEmailAndPassword and signInWithEmailAndPassword methods.

We will also need to create some basic forms in our Ionic App to let the user type his email and password and then a button to submit the values. To learn how to use forms and validations in ionic framework follow this super complete tutorial.

So, this is the code of our AuthService:

import { Injectable } from "@angular/core";
import 'rxjs/add/operator/toPromise';
import * as firebase from 'firebase/app';
import { FirebaseService } from './firebase.service';

@Injectable()
export class AuthService {

  constructor(private firebaseService: FirebaseService){}

  doRegister(value){
   return new Promise<any>((resolve, reject) => {
     firebase.auth().createUserWithEmailAndPassword(value.email, value.password)
     .then(
       res => resolve(res),
       err => reject(err))
   })
  }

  doLogin(value){
   return new Promise<any>((resolve, reject) => {
     firebase.auth().signInWithEmailAndPassword(value.email, value.password)
     .then(
       res => resolve(res),
       err => reject(err))
   })
  }

  doLogout(){
    return new Promise((resolve, reject) => {
      if(firebase.auth().currentUser){
        firebase.auth().signOut()
        .then(() => {
          this.firebaseService.unsubscribeOnLogOut();
          resolve();
        }).catch((error) => {
          reject();
        });
      }
    })
  }
}

And this is the html code of our register form page with its corresponding validations:

<form class="form" [formGroup]="validations_form"  (ngSubmit)="tryRegister(validations_form.value)">
  <ion-item>
    <ion-label floating color="primary">Email</ion-label>
    <ion-input type="text" formControlName="email"></ion-input>
  </ion-item>
  <div class="validation-errors">
    <ng-container *ngFor="let validation of validation_messages.email">
      <div class="error-message" *ngIf="validations_form.get('email').hasError(validation.type) && (validations_form.get('email').dirty || validations_form.get('email').touched)">
        {{ validation.message }}
      </div>
    </ng-container>
  </div>

  <ion-item>
    <ion-label floating color="primary">Password</ion-label>
    <ion-input type="password" formControlName="password" class="form-controll" required></ion-input>
  </ion-item>
  <div class="validation-errors">
    <ng-container *ngFor="let validation of validation_messages.password">
      <div class="error-message" *ngIf="validations_form.get('password').hasError(validation.type) && (validations_form.get('password').dirty || validations_form.get('password').touched)">
        {{ validation.message }}
      </div>
    </ng-container>
  </div>

  <button class="submit-btn" ion-button block type="submit" [disabled]="!validations_form.valid">Register</button>
  <label class="error-message">{{errorMessage}}</label>
  <label class="success-message">{{successMessage}}</label>
</form>

If you want to implement a more complete authentication with Firebase and Ionic I recommend reading Firebase Authentication in Ionic Framework Apps where we explain how to create an Ionic Framework application that offers authentication with social providers (such as with facebook, google and twitter) as well as with email and password.

In Ion2FullApp ELITE - our most popular Ionic 3 Starter App you will find a ready-made example of how to use Firebase Authentication and Firebase CRUD operations inside a real Ionic Framework Application. Using a template will save you lots of development time and will give your app a proffesional look.

These are some of the Ionic pages you can find in the Firebase Integration section of Ion2FullApp ELITE.

The functionalities of this ionic firebase integration include: authentication with different providers, feed with search filters, profile page with image handling (for profile picture) and all the CRUD operations.

Ion2FullApp Ionic Firebase Authentication
Ion2FullApp Firebase Ionic
Ion2FullApp Firebase CRUD

Firebase CRUD with Ionic Framework

Now we’ll see how to implement the CRUD functions in our Ionic Framework App using Firebase.

CREATE A TASK

We'll start with the functionality of Creating a Task, so we’ll implement a createTask() method in the firebase.service.ts service with the following code:

createTask(value){
   return new Promise<any>((resolve, reject) => {
     let currentUser = firebase.auth().currentUser;
     this.afs.collection('people').doc(currentUser.uid).collection('tasks').add({
       title: value.title,
       description: value.description,
       image: value.image
     })
     .then(
       res => resolve(res),
       err => reject(err)
     )
   })
 }

As mentioned above, the tasks are going to be assigned to the logged-in user, so we’ll use the firebase.auth().currentUser method to get their uid.

IMPORTANT: Note that the value.image from the code above must be the download URL that we’ll now explain how to get.

As we can see, each task has an image that has been selected from the cell phone’s image gallery, using the Image Picker plugin, and which has been saved in the Cloud Storage. How do we achieve this? Very simple, follow these 3 steps:

  1. Define the source from which we’ll store the image in the storage:
    let storageRef = firebase.storage().ref();
    let imageRef = storageRef.child('image').child('imageName');
  2. Then we must convert the URI that comes from the ImagePicker plugin to a base64 url. To do this we’ll use a canvas.
    encodeImageUri(imageUri, callback) {
      var c = document.createElement('canvas');
      var ctx = c.getContext("2d");
      var img = new Image();
      img.onload = function () {
        var aux:any = this;
        c.width = aux.width;
        c.height = aux.height;
        ctx.drawImage(img, 0, 0);
        var dataURL = c.toDataURL("image/jpeg");
        callback(dataURL);
      };
      img.src = imageUri;
    };
  3. And as a final step we’ll use the putString(image64, 'data_url') firebase method whose response gives us the url that was assigned to the image uploaded to the firebase storage. We can access that url by using snapshot.ref.getDownloadURL(). Then, the final method will be the following
    uploadImage(imageURI, randomId){
      return new Promise<any>((resolve, reject) => {
        let storageRef = firebase.storage().ref();
        let imageRef = storageRef.child('image').child(randomId);
        this.encodeImageUri(imageURI, function(image64){
          imageRef.putString(image64, 'data_url')
          .then(snapshot => {
            snapshot.ref.getDownloadURL()
            .then(res => resolve(res))
          }, err => {
            reject(err);
          })
        })
      })
    }

LIST TASKS

Once we’ve created one or more tasks, we’ll be able to list them. To get all the user tasks we’ll implement a getTasks() method in the service.

getTasks(){
  return new Promise<any>((resolve, reject) => {
    let currentUser = firebase.auth().currentUser;
    this.snapshotChangesSubscription = this.afs.collection('people').doc(currentUser.uid).collection('tasks').snapshotChanges()
    .subscribe(snapshots => {
      resolve(snapshots);
    })
  });
}

It’s very important to use the snapshotChanges() method since the answer gives us each Task’s id, which will be then used when updating and deleting the tasks.

The method to obtain data from a collection is valueChanges() which gives us a json with that Task’s attributes, but without its id. For more information about these two options visit this link.

UPDATE A TASK

Now we’ll proceed with the updateTask() method that receives as a parameter the id of the task to be updated, as well as its new value.

updateTask(taskKey, value){
  return new Promise<any>((resolve, reject) => {
    let currentUser = firebase.auth().currentUser;
    this.afs.collection('people').doc(currentUser.uid).collection('tasks').doc(taskKey).set(value)
    .then(
      res => resolve(res),
      err => reject(err)
    )
  })
}

It’s important to notice that if a Task’s values are to be modified, the new value should maintain the previous value, that is, if you want to update the image attribute of Task X, the value parameter must contain its description and current title.

DELETE A TASK

Deleting a Task is very simple, you only need to know the id of the Task to be deleted.

deleteTask(taskKey){
  return new Promise<any>((resolve, reject) => {
    let currentUser = firebase.auth().currentUser;
    this.afs.collection('people').doc(currentUser.uid).collection('tasks').doc(taskKey).delete()
    .then(
      res => resolve(res),
      err => reject(err)
    )
  })
}

Keep Learning Ionic and Firebase

Hopefully, you didn't run into any issues with this Firebase and Ionic step by step tutorial, but if you did, feel free to post in the comments section below. Remember you can get the full source code of this Ionic 3 app by clicking the GET THE CODE button from the beginning of this page.

In this Ionic and Firebase tutorial we learned how to perform a simple CRUD using Cloud Firestore in an Ionic 3 application to list, create, edit and delete tasks.

We also saw the different ways to obtain data in a firebase collection: valueChanges() and snapshotChanges().

As a bonus, we don’t only save an image in the Cloud Storage, but we also teach you how to get a download url to store it in the firebase database.

I hope this tutorial on how to create a CRUD with Firebase and Ionic Framework has been useful and remember that if you have any questions or suggestions you can leave us a comment below.

We have dozens of Ionic tutorials where you can learn to create the best mobile applications with Ionic Framework. If you want to learn more about Firebase and Ionic visit this link.

I also want to take this opportunity to tell you that at IonicThemes we’ve created the most complete and beautiful template that you could ever develop with the Ionic Framework. It has many features, integrations and components that will surely make your Ionic Framework-made application stand out from the rest.