In this Ionic Firebase tutorial you will learn how to create a CRUD (Create, Read, Update, Delete) application using Firebase Cloud Firestore as a database and Firebase Cloud Storage as an image storage.

For this tutorial we are going to build a simple Ionic Framework application that allows users to log in and log out using email/password authentication with Firebase. Once they log in, they will be able to perform all the CRUD functionalities through a list of tasks. In other words, we are going to build a To-Do App with Firebase and Ionic.

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 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 Framework. to learn Ionic 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 tutorial, we will show you how to create an Ionic Firebase CRUD.

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 Firebase guide you will learn the following:

  • How to create an Ionic application and install the required dependencies
  • How to create a Firebase application
  • How to connect the Ionic app with the Firebase app
  • How to perform a simple login with Firebase from an Ionic app
  • How to write the Ionic code for the Firebase CRUD operations
  • How to upload an image from an Ionic app to Firebase storage

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. Also, you can use our latest Ionic 6 Full Starter App as a base for your project

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

Ionic firebase app
Ionic Firebase app
Ionic Firebase app
Ionic Firebase app
Ionic Firebase app
Ionic Firebase app

To integrate our Ionic app with the Firebase project we'll use the AngularFire library.

I will 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 @angular/fire firebase --save

We will also have to install the Image Picker Cordova plugin. We are going to use this plugin to access the gallery of images on your cell phone and thus be able to create tasks with images that we can then store in Firebase Storage.

Ionic Image Picker plugin requires cordova-plugin-image-picker, so you should also install it.

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 @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, check Image handling in Ionic apps.

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:

create Firebase app

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.

Firebase app credentials

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 need to replace the constants with your own values.

Now we’re ready to start building the Ionic Firebase CRUD.

To build 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

First you need to enable Authentication in your Firebase Project. To do this go back to the Firebase console and click on Authentication tab.

Firebase app credentials

Now click the "Set up sign-in method" button. You will be able to select the authentication providers you want to configure for your app. For this app we will only enable the Email/Password option. We have another tutorial explaining how to add social providers such as Facebook.

Firebase app credentials

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 into 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. Learn how to use Forms in Ionic Framework.

Below is the code of our AuthService:

import { Injectable } from "@angular/core";
import * as firebase from 'firebase/app';
import { FirebaseService } from './firebase.service';
import { AngularFireAuth } from '@angular/fire/auth';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(
    private firebaseService: FirebaseService,
    public afAuth: AngularFireAuth
  ){}

  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) => {
      this.afAuth.auth.signOut()
      .then(() => {
        this.firebaseService.unsubscribeOnLogOut();
        resolve();
      }).catch((error) => {
        reject();
      });
    })
  }
}

And below is the HTML code of our register form page with its corresponding from validations:

<form class="form" [formGroup]="validations_form" (ngSubmit)="tryRegister(validations_form.value)">
  <ion-item>
    <ion-label position="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 position="floating" color="primary">Password</ion-label>
    <ion-input type="password" formControlName="password"></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>

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

If you want to add more authentication providers to your Ionic app, check 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.

Did you know that we recently released Ionic 6 Full Starter App — PRO? It's an Ionic 5 template that you can use to jump start your Ionic app development and save yourself hundreds of hours of design and development.

It includes Firebase Authentication and a complete CRUD example.

Ionic starter app

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 will now explain how to get.

Upload the image to Firebase

For this Ionic Firebase example app, we use the image picker Cordova plugin to access the image gallery. This means that this will only work on mobile, and not in the browser. If you want to add support for browser you can use the Capacitor Camera API.

As we can see, each task has an image that has been selected from the 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 FirebaseService.

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

It’s very important to use the snapshotChanges() method since the answer gives us each task 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 attributes, but without its ID. For more information about these two options visit the Firebase documentation.


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)
    )
  })
}

If the values from the task 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)
    )
  })
}

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 Firebase 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 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 Ionic 6 Full Starter App — PRO. It has many features, integrations and components that will surely make your Ionic Angular app stand out from the rest!