Firebase Firestore CRUD Operations in Ionic Angular Applications

imgg



Ionic & Angular With Firebase CRUD Operations: This step-by-step example will explain how to make a mobile CRUD operations app in Ionic using Google Firebase NoSQL real-time database.

CRUD, which stands for Create, Read, Update, and Delete, is a fundamental building block for every web and mobile app.


It is called CRUD. The word "create" means to add or make new data objects in the database.

Reading means getting data objects from the database and putting them on the view. Update means changing or updating the data, and delete means removing the data object from the database.

This Ionic CRUD tutorial will help people just starting in application development by showing them how to deal with Ionic Firebase CRUD in the best way possible.

In this Ionic Firebase CRUD example, we'll show you how to use Firestore to build CRUD operations for native mobile apps using the Ionic and Angular frameworks.

Ionic 6 & Angular CRUD Operations With Firebase

We'll make an Ionic to-do app, starting with setting up an Ionic and Angular environment, adding firestore to Ionic, and connecting with Ionic and Firebase.

Our Ionic Angular ToDo App will be a simple app with an easy-to-use interface that helps us keep track of our daily tasks.

Users can create tasks, list all tasks, change an existing lesson, or delete a current job. Below are the steps you need to take to put together the app.

  • Step 1: Creating A New Ionic Project
  • Step 2: Create Firebase Project
  • Step 3: Install Firebase & AngularFire Packages
  • Step 4: Change Environment Files
  • Step 5: Change Routing Module
  • Step 6: Add Navigation Routes
  • Step 7: Add Angular Service
  • Step 8: Create
  • Step 9: Read & Delete
  • Step 10: Update
  • Step 11: Test Ionic App

Creating A New Ionic Project

In the first step, you have to install Ionic CLI, which lets you start ionic development on your system.


npm install -g @ionic/cli
Bash


Now, you begin the installation of the Ionic Angular app:

ionic start todo blank --type=angular
Bash

Next, head over to the app folder:

cd todo
Bash

To make the Todo CRUD app, we need to make a few pages. To make the new pages, run the following commands from the terminal. We don’t need the Home page, so delete the default Home page component.

ng generate page create-todo

ng generate page update-todo

ng generate page todo-list
Bash

Create Firebase Project

In this step, we'll learn how to make a new Firebase project to get the Firebase configuration keys. Use it with the AngularFire package to connect with Ionic and Firestore.

You must go to the Firebase website and open the Firebase console.

Next, give your project a name in the "Create a project" box.

After that, you need to add Firebase to your app, so click on the "Web icon" to get started.

Then, add Firebase to your web app's screen manifests. You'll need to give the app a name and click "Register App."

Simply copy the Firebase SDK keys & save it somewhere. You will need these configuration keys soon.


Also, click on Firestore and create a Cloud Firestore database for real-time updates, powerful queries, and automatic scaling. "Test mode" should be chosen for the demo.

Install Firebase & AngularFire Packages

Now, you have to add the FirebaseAngularFire packages to the Ionic app and then run the following command:

npm i firebase @angular/fire
Bash

Change Environment Files

Let's add the Firebase configuration keys to the angular environment files. Add the Firebase keys to the environment.ts and environment.prod.ts files one after the other.

// environment.prod.ts ( You need configure Firebase here )

export const environment = { // This will export environment
  production: true, // set this true
  firebaseConfig: {
    apiKey: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK Keys
    authDomain: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK Keys
    projectId: 'xxxxxxxxx', // From Firebase SDK Keys
    storageBucket: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK keys
    messagingSenderId: 'xxxxxxxxxx', // From Firebase SDK keys
    appId: 'xxxxxxxxxxxxxxxxxxxx'// From Firebase SDK Keys
  }
};
TypeScript
// environment.prod.ts ( You need configure Firebase here )

export const environment = { // This will export environment
  production: true, // set this false
  firebaseConfig: {
    apiKey: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK Keys
    authDomain: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK Keys
    projectId: 'xxxxxxxxx', // From Firebase SDK Keys
    storageBucket: 'xxxxxxxxxxxxxxxxxxxx', // From Firebase SDK keys
    messagingSenderId: 'xxxxxxxxxx', // From Firebase SDK keys
    appId: 'xxxxxxxxxxxxxxxxxxxx'// From Firebase SDK Keys
  }
};
TypeScript

Change App Module

Now that we have added the AngularFire Modules & Environment variable to the main app module class, Ionic can connect to the Firebase database.

Update app.module.ts file:

// Other Imports

//  Firebase modules
import { AngularFireModule } from '@angular/fire'; // AngularFireModule Import 
import { AngularFireDatabaseModule } from '@angular/fire/database'; // AngularFireDatabaseModule

// Environment
import { environment } from '../environments/environment'; // Import Environment

@NgModule({
  declarations: [AppComponent], // App Component Import
  entryComponents: [], // Your Entry Components
  imports: [
    ....,     
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFireDatabaseModule
  ],
  providers: [
    ..., // Your Providers
    ],
  bootstrap: [AppComponent],
})

export class AppModule {}
TypeScript

Change Routing Module

To handle CRUD operations, you have to make small changes to the app routing file:


Update the app/app-routing.ts file:

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '', 
    redirectTo: 'create-task', 
    pathMatch: 'full'
  },
  {
    path: 'create-task',
    loadChildren: () => import('./fake-path/fake.module').then( m => m.FakePageModule)
}, { path: 'update-todo/:id', loadChildren: () => import('./fake-path/fake.module').then( m => m.FakePageModule) }, { path: 'todo-list', loadChildren: () => import('./fake-path/fake.module').then( m => m.FakePageModule)
}, ]; @NgModule({ imports: [ RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) ], exports: [RouterModule] }) export class AppRoutingModule { }
TypeScript

Add Navigation Routes

You need to define tab routes to move around in the crud todo app, so open the app.component.html file and change the code below.

<ion-app>
  <ion-router-outlet></ion-router-outlet>
</ion-app>

<!-- Navigation tabs -->
<ion-tabs>
  <ion-tab-bar slot="bottom">
    <ion-tab-button routerLinkActive="tab-selected" routerLink="/todo-list" tab="todo-list">
      <ion-icon name="list-outline"></ion-icon>
      <ion-label>Tasks</ion-label>
    </ion-tab-button>

    <ion-tab-button routerLinkActive="tab-selected" routerLink="/create-task" tab="create-task">
      <ion-icon name="add-circle-outline"></ion-icon>
      <ion-label>Create Task</ion-label>
    </ion-tab-button>
  </ion-tab-bar>
</ion-tabs>
Markup

Create Angular Service

Then, create an Angular service to make a reusable part that handles the custom methods for CRUD Operations.

ng generate service services/crud
Bash

Declare the TODO class to define the task's schema, import AngularFirestore, and inject it into the page's constructor. It gives you access to the Firestore methods, and it's easy to make your methods for CRUD operations.

Update services/crud.service.ts file:

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Router } from "@angular/router";

export class TODO {
  $key: string;
  title: string;
  description: string;
}

@Injectable({
  providedIn: 'root'
})

export class CrudService { // Class 

  constructor(
    private ngFirestore: AngularFirestore, // Declaration
    private router: Router
  ) { }

  create(todo: TODO) {
    return this.ngFirestore.collection('tasks').add(todo); // creating
  }

  getTasks() {
    return this.ngFirestore.collection('tasks').snapshotChanges(); // fetching
  }
  
  getTask(id: any) {
    return this.ngFirestore.collection('tasks').doc(id).valueChanges(); // fetching single 
  }

  update(id: any, todo: TODO) { // updating
    this.ngFirestore.collection('tasks').doc(id).update(todo)
      .then(() => {
        this.router.navigate(['/todo-list']);
      }).catch(error => console.log(error));;
  }

  delete(id: string) {
    this.ngFirestore.doc('tasks/' + id).delete(); // delete
  }

}
TypeScript

Create

You can use reactive forms to work with form components. To do this, add the ReactiveFormsModule to the page-specific module file. So, add the following code to the file create-todo.module.ts:


import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    ReactiveFormsModule
  ]
})
TypeScript

Make a simple form and add two form controls with title and description fields.

Update create-todo.page.html file:

<ion-header>
  <ion-toolbar>
    <ion-title>Create Task</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
  <form [formGroup]="todoForm" (ngSubmit)="onSubmit()">
    <ion-item>
      <ion-label position="floating">Title</ion-label>
      <ion-input formControlName="title" type="text" required></ion-input>
    </ion-item>

    <ion-item>
      <ion-label position="floating">Description</ion-label>
      <ion-input formControlName="description" type="text" required>
      </ion-input>
    </ion-item>

    <ion-button class="ion-margin-top" type="submit" expand="block" color="success">Create</ion-button>
  </form>
</ion-content>
Markup

The create() method stores the to-do task in the Firestore database. Then, use the router API to go to the to-do list page.

Update create-todo.page.ts file:

import { Component, OnInit } from '@angular/core';

import { CrudService } from './../services/crud.service';
import { FormGroup, FormBuilder } from "@angular/forms";
import { Router } from '@angular/router';

@Component({
  selector: 'app-create-todo',
  templateUrl: './create-todo.page.html',
  styleUrls: ['./create-todo.page.scss'],
})

export class CreateTodoPage implements OnInit {

  todoForm: FormGroup;

  constructor(
    private crudService: CrudService,
    public formBuilder: FormBuilder,    
    private router: Router
  ) { }

  ngOnInit() {
    this.todoForm = this.formBuilder.group({
      title: [''],
      description: ['']
    })
  }

  onSubmit() {
    if (!this.todoForm.valid) {
      return false;
    } else {
      this.crudService.create(this.todoForm.value)
      .then(() => {
        this.todoForm.reset();
        this.router.navigate(['/todo-list']);
      }).catch((err) => {
        console.log(err)
      });
    }
  }

}
TypeScript

Read & Delete

In this step, we'll get the list of tasks and show you how to delete the task object from the Firestore. Use the ion-list UI component to show the ionic data list, and add a button bind remove() function with a click event to get rid of the data object.

Update todo-list.page.html file:


<ion-header>
  <ion-toolbar>
    <ion-title>Todo List</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

  <ion-list>
    <ion-item *ngFor="let task of Tasks" lines="full">
      <ion-label>
        <strong>{{task.title}}</strong>
        <p>{{task.description}}</p>
      </ion-label>

      <div item-end>
        <button [routerLink]="['/update-todo/', task.id]">
          <ion-icon name="create" style="zoom:1.5"></ion-icon>
        </button>
        <button (click)="remove(task.id)">
          <ion-icon name="trash" style="zoom:1.5"></ion-icon>
        </button>
      </div>
    </ion-item>
  </ion-list>

</ion-content>
Markup

Update todo-list.page.ts file:

import { Component, OnInit } from '@angular/core';
import { CrudService } from './../services/crud.service';

export class TODO {
  $key: string;
  title: string;
  description: string;
}

@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.page.html',
  styleUrls: ['./todo-list.page.scss'],
})

export class TodoListPage implements OnInit {

  Tasks: TODO[];

  constructor(private crudService: CrudService) { }

  ngOnInit() {
    this.crudService.getTasks().subscribe((res) => {
      this.Tasks = res.map((t) => {
        return {
          id: t.payload.doc.id,
          ...t.payload.doc.data() as TODO
        };
      })
    });
  }

  todoList() {
    this.crudService.getTasks()
    .subscribe((data) => {
      console.log(data)
    })
  }

  remove(id) {
    console.log(id)
    if (window.confirm('Are you sure?')) {
      this.crudService.delete(id)
    }
  }  

}
TypeScript

Update

In this last example, you'll see how to use the activated route API and the custom update() method to get a single task object from the cloud firestore database.

Register the reactive forms module in the update-todo.module.ts file one more time:

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    ReactiveFormsModule
  ]
})
TypeScript

Update update-todo.page.html file:

<ion-header>
  <ion-toolbar>
    <ion-title>Update Task</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
  <form [formGroup]="editForm" (ngSubmit)="onSubmit()">
    <ion-item>
      <ion-label position="floating">Title</ion-label>
      <ion-input formControlName="title" type="text" required></ion-input>
    </ion-item>

    <ion-item>
      <ion-label position="floating">Description</ion-label>
      <ion-input formControlName="description" type="text" required>
      </ion-input>
    </ion-item>

    <ion-button class="ion-margin-top" type="submit" expand="block" color="success">Update</ion-button>
  </form>
</ion-content>
Markup

Update update-todo.page.ts file:

import { Component, OnInit } from '@angular/core';

import { CrudService } from './../services/crud.service';
import { Router, ActivatedRoute } from "@angular/router";
import { FormGroup, FormBuilder } from "@angular/forms";



@Component({
  selector: 'app-update-todo',
  templateUrl: './update-todo.page.html',
  styleUrls: ['./update-todo.page.scss'],
})

export class UpdateTodoPage implements OnInit {

  editForm: FormGroup;
  id: any;

  constructor(
    private crudService: CrudService,
    private activatedRoute: ActivatedRoute,
    private router: Router,
    public formBuilder: FormBuilder
  ) {
    this.id = this.activatedRoute.snapshot.paramMap.get('id');
    this.crudService.getTask(this.id).subscribe((data) => {
      this.editForm = this.formBuilder.group({
        title: [data['title']],
        description: [data['description']]
      })
    });
  }

  ngOnInit() {
    this.editForm = this.formBuilder.group({
      title: [''],
      description: ['']
    })    
  }

  onSubmit() {
    this.crudService.update(this.id, this.editForm.value)
  }

}
TypeScript

Test The Ionic App

Finally, we're ready to test our crud mobile app, so go to the command prompt and follow the instructions:


First, choose the platform where you want the app to run:

# iOS
ionic cordova platform add ios

# Android
ionic cordova platform add android

# Windows
ionic cordova platform add windows
Bash

Then, make the build that can be run:

# iOS
ionic cordova build ios

# Android
ionic cordova build android

# Windows
ionic cordova build windows
Bash

Run the app on the device in the end:

# iOS
ionic cordova run ios -l

# Android
ionic cordova run android -l

# Windows
ionic cordova run windows -l
Bash
imgb


Conclusion

So this is it for Ionic & Firestore CRUD operations tutorial. Using the Firebase NoSQL database, we built an excellent Todo CRUD application in Ionic Angular for the native mobile device.

You can comment below for any query or if you need any help. If you find our article helpful, subscribe to Us On YouTube for more. 

Post a Comment

0Comments
Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Accept !