In this Ionic 5 tutorial, we’ll integrate Google’s Firebase and use NoSQL database service Firestore to perform CRUD operation by creating a Student Resister application.
The Firestore is a cloud-based Realtime NoSQL database service provided by Firebase. We’ll integrate Firestore services in an Ionic application and build a Student Register application and perform CRUD (Create, Read, Update and Delete) operations.
In a traditional SQL based Relational Database Management system works with Tables and Rows, but in a NoSQL database like Firestore, we work with Collections and Documents. In a NoSQL, database information is saved and fetched in the form of JSON objects.
The Student Register application which we are going to create will have a form using which we’ll add a new document for each student having Name, Age and Address in the collection of Students. We’ll also add update, list and delete operation on Student collection.
Let’s begin…
Also See: How to Implement Firestore CRUD Operation in Angular 7/6 Application
# Update Ionic CLI
Run following npm command to update the Ionic CLI tool to the latest version
$ npm install -g @ionic/cli</pre> <h3># Create new Ionic application:</h3> Execute the following command to create a new Ionic Angular application with a <code>blank
template:$ ionic start ionic-firebase-crud-operations blank --type=angular </pre> then move to the root path of the application <pre class="wp-block-prismatic-blocks"><code class="language-javascript">$ cd ionic-firebase-crud-operations</pre> <h4></h4> <h3># Create a Firebase Project</h3> If you already having any Firebase project, you can use that or follow these steps to create one and enable Firestore database. After creating a Firebase project we will use credentials in our Ionic Application. <strong>Step 1)</strong> Visit <strong>Firebase</strong> <a href="https://firebase.google.com/" target="_blank" rel="noopener noreferrer">here</a> then click on Get Started if you have not created an account yet. <a href="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_6-1.png"><img class="alignnone wp-image-1857" src="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_6-1.png" alt="" width="287" height="209" /></a> <strong>Step 2)</strong> Click on "<strong>Add project</strong>" then enter app-related information click on "<strong>Create project</strong>" <a href="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_7-1.png"><img class="alignnone size-full wp-image-1858" src="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_7-1.png" alt="" width="523" height="504" /></a> <strong>Step 3)</strong> Next click on "<strong>Web App</strong>" icon to get configuration text with app secret info which we will add in our Ionic Application to communicate with services related to this Firebase project. <a href="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_8-1.png"><img class="alignnone wp-image-1859" src="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_8-1.png" alt="" width="336" height="236" /></a><a href="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_9-1.png"><img class="alignnone wp-image-1860" src="https://www.freakyjolly.com/wp-content/uploads/2019/02/Screenshot_9-1.png" alt="" width="402" height="277" /></a> <strong>Step 4) </strong>Then enable Firestore Database service in your Firebase project. On the left sidebar select Database, then click on the <strong>Create</strong> button. This will enable the Database service for our Firebase application. Now we are ready to connect our Ionic application with this Firebase application. <h3></h3> <h3># Adding Firebase Credentials in Ionic 5 Application</h3> Now we need to add the Firebase application credential in the Ionic application to create a connection. Open the Environment file at location "~ionic-firebase-crud-operations/src/environments<strong>/environment.ts</strong>" then update it with your credential as shown below: <pre class="wp-block-prismatic-blocks"><code class="language-javascript">export const environment = { production: false, firebase: { apiKey: "[YOUR_apiKey_HERE]", authDomain: "[YOUR_authDomain_HERE]", databaseURL: "[YOUR_databaseURL_HERE]", projectId: "[YOUR_projectId_HERE]", storageBucket: "[YOUR_storageBucket_HERE]", messagingSenderId: "[YOUR_messagingSenderId_HERE]", appId: "[YOUR_appId_HERE]" } };</pre> <h3></h3> <h3># Install Firebase in Application</h3> To integrate Firebase services, we'll install <code>angularfire
package in the Ionic Angular application. It is a Firebase official package for Angular applications. This package lets an Angular project to use all Firebase services. As a dependency, we also need to install thefirebase
package which will work under the hood withangularfire
. Install these packages by running following npm command in the terminal window$ npm install firebase @angular/fire --save</pre> <h3># Import Firebase Modules</h3> We need to import the required <code>AngularFireModule
and also theAngularFirestoreModule
to use the Firestore NoSQL database service. To create a connection between Firebase application with Ionic Angular application, we will use theAngularFireModule
'sinitializeApp
method to takeenvironment.firebase
credentials. After making above changes the app.module.ts file will look like this// app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { environment } from 'src/environments/environment'; import { AngularFireModule } from '@angular/fire'; import { AngularFirestoreModule } from '@angular/fire/firestore'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [ BrowserModule, IonicModule.forRoot(), AppRoutingModule, AngularFireModule.initializeApp(environment.firebase), AngularFirestoreModule ], providers: [ StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule { }by following above steps your application is connected with Firebase and ready to perform CRUD operation on Firestore Database.
# Create a Service with Firestore CRUD methods
Now we'll create a new service to perform CRUD operation by using methods available in the AngularFirestore class.
Run the following
ionic generate
command to createfirebaseService
in the services folder in the Ionic application.$ ionic generate service services/firebase</pre> <h3># Update the FirebaseService with CRUD methods</h3> After creating the service at location "~ionic-firebase-crud-operations/src/app/service/<strong>firebase.service.ts</strong>", update it with CRUD methods <div>Replace below code in the <strong>firebase.service.ts</strong> file</div> <div> <pre class="wp-block-prismatic-blocks"><code class="language-javascript">// firebase.service.ts import { Injectable } from '@angular/core'; import { AngularFirestore } from '@angular/fire/firestore'; @Injectable({ providedIn: 'root' }) export class FirebaseService { collectionName = 'Students'; constructor( private firestore: AngularFirestore ) { } create_student(record) { return this.firestore.collection(this.collectionName).add(record); } read_students() { return this.firestore.collection(this.collectionName).snapshotChanges(); } update_student(recordID, record) { this.firestore.doc(this.collectionName + '/' + recordID).update(record); } delete_student(record_id) { this.firestore.doc(this.collectionName + '/' + record_id).delete(); } } </pre> <div>In the above service, import the <code>AngularFirestore
class to use its methods. Following are the methods doing operations onStudents
collection and manipulating the documents.<strong>create_student()</strong>
: Create a new record in the specified collection by calling theadd()
method<strong>read_students()</strong>
: CallsnapshotChanges()
method which will get records and also subscribe it to get updates<strong>update_student()</strong>
: Thedoc()
method takes collection name with document id to update the record, then theupdate()
method is called to save the document.<strong>delete_student()</strong>
: Like update the doc() method takes collection name with id todelete()
the document.# Update User Interface in the Home Page
The final step is to create a page for User Interaction where we can create a new record and can view all rows available in the collection. A user can also click on Edit and Delete buttons to perform record actions. In edit mode, the user can Cancel or Update changes. To keep tutorial simple we will update existing home component which is created by default in blank Ionic 4 template.# Add Student Form and List
We have a form with[formGroup]
for reactive form validation and(ngSubmit)
event handler. There are three input controls forName
,Age
andAddress
havingformControlName
property on each to get value and validation. The list of Students is shown in theion-card
component. This is having conditional blocks for Edit mode.<ion-header [translucent]="true"> <ion-toolbar color="warning"> <ion-title> Student Register </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true" class="ion-padding"> <form [formGroup]="studentForm" (ngSubmit)="CreateRecord()"> <ion-item> <ion-label position="floating">Name</ion-label> <ion-input formControlName="Name"></ion-input> </ion-item> <ion-item> <ion-label position="floating">Age</ion-label> <ion-input formControlName="Age"></ion-input> </ion-item> <ion-item> <ion-label position="floating">Address</ion-label> <ion-input formControlName="Address"></ion-input> </ion-item> <ion-item> <ion-button (click)="CreateRecord()" [disabled]="studentForm.invalid"> <ion-icon size="small" slot="icon-only" name="add"></ion-icon> Create Record </ion-button> </ion-item> </form> <ion-card *ngFor="let item of studentList" color="primary"> <span *ngIf="!item.isEdit; else elseBlock"> <ion-card-header> <ion-card-title>{{item.Name}} of {{item.Age}} years</ion-card-title> <ion-card-subtitle>From: {{item.Address}}</ion-card-subtitle> </ion-card-header> <ion-card-content> <ion-button shape="round" color="secondary" size="small" (click)="EditRecord(item)"> <ion-icon size="small" slot="icon-only" name="create"></ion-icon> </ion-button> <ion-button shape="round" color="danger" size="small" (click)="RemoveRecord(item.id)"> <ion-icon size="small" slot="icon-only" name="trash"></ion-icon> </ion-button> </ion-card-content> </span> <ng-template #elseBlock> <ion-card-header> <ion-card-title> <ion-grid> <ion-row> <ion-col> Edit </ion-col> <ion-col> <ion-button fill="solid" color="medium" size="small" (click)="item.isEdit = false"> Cancel </ion-button> </ion-col> <ion-col> <ion-button fill="solid" color="success" size="small" (click)="UpdateRecord(item)"> Update </ion-button> </ion-col> </ion-row> </ion-grid> </ion-card-title> </ion-card-header> <ion-card-content> <ion-item> <ion-label><strong>Name</strong></ion-label> <ion-input type="text" [(ngModel)]="item.EditName"></ion-input> </ion-item> <ion-item> <ion-label><strong>Age</strong></ion-label> <ion-input type="text" [(ngModel)]="item.EditAge"></ion-input> </ion-item> <ion-item> <ion-label><strong>Address</strong></ion-label> <ion-input type="text" [(ngModel)]="item.EditAddress"></ion-input> </ion-item> </ion-card-content> </ng-template> </ion-card> </ion-content></pre> </div> <div> <h3># Update Home Class</h3> Replace following code in the <strong>home.page.ts</strong> file <pre class="wp-block-prismatic-blocks"><code class="language-javascript">// home.page.ts import { Component } from '@angular/core'; import { FirebaseService } from '../services/firebase.service'; import { FormGroup, Validators, FormBuilder } from '@angular/forms'; interface StudentData { Name: string; Age: number; Address: string; } @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], }) export class HomePage { studentList = []; studentData: StudentData; studentForm: FormGroup; constructor( private firebaseService: FirebaseService, public fb: FormBuilder ) { this.studentData = {} as StudentData; } ngOnInit() { this.studentForm = this.fb.group({ Name: ['', [Validators.required]], Age: ['', [Validators.required]], Address: ['', [Validators.required]] }) this.firebaseService.read_students().subscribe(data => { this.studentList = data.map(e => { return { id: e.payload.doc.id, isEdit: false, Name: e.payload.doc.data()['Name'], Age: e.payload.doc.data()['Age'], Address: e.payload.doc.data()['Address'], }; }) console.log(this.studentList); }); } CreateRecord() { console.log(this.studentForm.value); this.firebaseService.create_student(this.studentForm.value).then(resp => { this.studentForm.reset(); }) .catch(error => { console.log(error); }); } RemoveRecord(rowID) { this.firebaseService.delete_student(rowID); } EditRecord(record) { record.isEdit = true; record.EditName = record.Name; record.EditAge = record.Age; record.EditAddress = record.Address; } UpdateRecord(recordRow) { let record = {}; record['Name'] = recordRow.EditName; record['Age'] = recordRow.EditAge; record['Address'] = recordRow.EditAddress; this.firebaseService.update_student(recordRow.id, record); recordRow.isEdit = false; } } </pre> First, we have initialized the Form with FormGroup. <pre class="wp-block-prismatic-blocks"><code class="language-javascript">studentForm: FormGroup;</pre> The data will be of <code>interface
typeStudentData
defined in the class.interface StudentData { Name: string; Age: number; Address: string; }</pre> Then create a group of the form using <code>FormBuilder
class method and define required validation.this.studentForm = this.fb.group({ Name: ['', [Validators.required]], Age: ['', [Validators.required]], Address: ['', [Validators.required]] })</pre> On page init, we will call the<code> read_student()
service method to fetch the existing list of items saved in the Firestore collection and subscribe to them. So whenever there will be a change in the Firestore data during CRUD operations, the changes will be updated in real-time as we called thesnapshotChanges()
method on theStudents
collection.this.firebaseService.read_students().subscribe(data => { this.studentList = data.map(e => { return { id: e.payload.doc.id, isEdit: false, Name: e.payload.doc.data()['Name'], Age: e.payload.doc.data()['Age'], Address: e.payload.doc.data()['Address'], }; }) });</pre> The <code>CreateRecord()
method will take form values to submit to the Forestore by calling thecreate_student()
service method. On success, we are resetting the form.CreateRecord() { this.firebaseService.create_student(this.studentForm.value) .then(resp => { //Reset form this.studentForm.reset(); }) .catch(error => { console.log(error); }); }</pre> On clicking the Edit icon we are setting the actual values in temporary fields using the <code>EditRecord()
method so that we can show actual values if the user clicks the cancel buttonEditRecord(record) { record.isEdit = true; record.EditName = record.Name; record.EditAge = record.Age; record.EditAddress = record.Address; }</pre> On hitting the update button in edit mode the changed values will be updated by calling the<code> update_student()
method in service.UpdateRecord(recordRow) { let record = {}; record['Name'] = recordRow.EditName; record['Age'] = recordRow.EditAge; record['Address'] = recordRow.EditAddress; this.firebaseService.update_student(recordRow.id, record); recordRow.isEdit = false; }</pre> <h3># Import ReactiveFormModule for FormValidation</h3> As we are using Reactive Form approach for validating the form for creating Student, we need to import the <code>ReactiveFormsModule
in the home.module.ts file as shown below:// home.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HomePage } from './home.page'; import { HomePageRoutingModule } from './home-routing.module'; @NgModule({ imports: [ CommonModule, FormsModule, ReactiveFormsModule, IonicModule, HomePageRoutingModule ], declarations: [HomePage] }) export class HomePageModule { }
That's it now you can run the application in your browser by running
$ ionic serve --open
Get source code of this tutorial in GitHub repo here.
Conclusion: We discussed on how we can integrate Firebase service in Ionic Angular application. We used the Firestore to perform CRUD operation using NoSQL real-time database service to create a Students register here. You can use any service in a similar way like Authentication of users by Email and Password.
Category: Firebase