In this blog post we will learn how to create a simple Notes application using Ionic 5 and Angular 12.
The Note application will be able to perform the read, create, update and delete operations, and Firestore database in the Firebase will be used as database.
The Note Application
We will cover following topics:
- Setting up the Firebase project to save notes
- Creating a new Ionic 5 Angular type application.
- Configuring the Ionic application to support Firebase
- Creating Firebase Service to perform CRUD operations with Firestore.
- Creating List page to show all records from Firebase.
- Creating Display page to show single record from Firebase.
- Creating Create page to add new record in Firebase
- Creating Update Page to update a record in Firebase.
- Deleting a record from Firebase.
- Conclusion
Setting up the Firebase Project to save notes
For our Notes app we are going to save notes in the Firebase, and for that we need to create a new Firebase project. If you have existing Firebase project you can also use that.
Creating a Firebase project
To create a Firebase project head over to Firebase console and click on Add Project.

Give your project a name, it’s Notes in my case.
You can change your project’s unique name here, although that doesn’t matters.

Enable Google Analytics to your project (optionally).

If you have chosen to enable Google Analytics then select or create the account for the Google Analytics.

In the following I have selected a new Google Analytics account.

Then finally click on create project.
This will take a few minutes to setup the new Firebase project.


Click on continue.
and now we are inside the our brand new Firebase project.

Getting Firestore Database settings.
To store the Notes inside Firebase, we need some configuration settings from the Firebase project.
To get the settings, go to the Project settings.

Select the web app options from available platform options.

Click on Register app.

Copy the firebaseConfig from the next screen. We are going to need this in our Ionic app.

Then click on Continue to console at the bottom of the screen.
In the firebaseConfig one setting is missing in my case i.e. databaseURL.
The databaseURL specifies to which database data will be saved.
If this is missing in your case too, then add like following.
var firebaseConfig = {
apiKey: "AIzaSyDv6oqHgHBOV60BpXa0W_JSxKDOrYuT7_M",
authDomain: "notes-3b077.firebaseapp.com",
projectId: "notes-3b077",
databaseURL: "https://notes-3b077.firebaseio.com/",
storageBucket: "notes-3b077.appspot.com",
messagingSenderId: "435123651850",
appId: "1:435123651850:web:6f2e0f5f60decf031166f3",
measurementId: "G-ZBDCPDDNFX"
};
databaseUrl format is as following.
https://{your-app-unique-name}.firebaseio.com/
We have now created the Firebase project, and we have the required configurations.
Let’s now create our Ionic application for saving the notes.
Creating a new Ionic Application of Angular Type
At the time of writing the latest version available for Ionic is Ionic 5. and Angular has the latest version of 12.
To create an Ionic application we need the Ionic CLI.
Install Ionic CLI globally or update it to the latest version if you have already installed.
npm install -g @ionic/cli
Create a new Ionic application of Angular type with blank template.
ionic start ionic-firebase-crud blank --type=angular
Move to the ionic app you have just created.
cd ionic-firebase-crud
Configuring the Ionic application to support Firebase
Before we can start saving notes in the Firebase from Notes app, we need to add configurations.
Adding Firebase Configurations in the Application
Add the firebaseConfig that we copied earlier in the environment.ts file.

Installing Required Firebase packages in the Ionic Application
To work with Firebase we need to add few npm packages.
- firebase
- @angular/fire
Install the firebase and @angualr/fire using npm and save it to the package.json file.
npm install firebase @angular/fire --save
This will add the following highlighted dependencies in the package.json
"dependencies": {
"@angular/common": "~12.0.1",
"@angular/core": "~12.0.1",
"@angular/fire": "^6.1.5",
"@angular/forms": "~12.0.1",
"@angular/platform-browser": "~12.0.1",
"@angular/platform-browser-dynamic": "~12.0.1",
"@angular/router": "~12.0.1",
"@ionic/angular": "^5.5.2",
"firebase": "^8.6.8",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.4"
},
Adding Firebase modules in the application
Import AngularFireModule and AngularFirestoreModule modules in the 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 { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
// Firebase
import { AngularFireModule } from '@angular/fire';
import { AngularFirestoreModule} from '@angular/fire/firestore';
//Environment
import { environment } from 'src/environments/environment';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFirestoreModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}
The configuration for the Firebase is complete now.
Adding Note Model class
Note will be our domain model for the application.
Add a model class for Notes.
export class Note{
id: string;
title: string;
content: string;
}
Let’s now create a service to handle the Firebase CRUD operations.
Creating Firebase Service to perform CRUD operations with Firestore
Create a new service class FirebaseService for handling Firebase CRUD operations.
ionic generate service services/firebase
or
ionic g s services/firebase
Create and initialize collectionName field to store Note’s collection name.
private collectionName: string = "notes";
Pass AngularFirestore Dependency Injection in Service class constructor.
constructor(private firestore: AngularFirestore) { }
Add addNote method for creating a note.
addNote(note: Note) {
return this.firestore.collection(this.collectionName).add({...note});
}
Add getNote method to get a single note.
getNote(id: string): Observable<Note>
{
return this.firestore.collection(this.collectionName).doc<Note>(id).snapshotChanges()
.pipe(
map(a => {
const id = a.payload.id;
const data = a.payload.data();
return { id, ...data };
})
);
}
Add getNotes method to get all the notes.
getNotes(): Observable<Note[]> {
return this.firestore.collection<Note>(this.collectionName).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const id = a.payload.doc.id;
const data = a.payload.doc.data();
return { id, ...data };
});
})
);
}
Add updateNote method to update the note.
updateNote(id: string, note: Note): Promise<void> {
return this.firestore.collection(this.collectionName).doc<Note>(id).update(note);
}
Add deleteNote method to delete a note.
deleteNote(id: string): Promise<void> {
return this.firestore.collection(this.collectionName).doc(id).delete();
}
Completed FirebaseService service class should look as following.
import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Note } from '../models/note';
@Injectable({
providedIn: 'root'
})
export class FirebaseService {
private collectionName: string = "notes";
constructor(private firestore: AngularFirestore) { }
addNote(note: Note) {
return this.firestore.collection(this.collectionName).add({...note});
}
getNote(id: string): Observable<Note>
{
return this.firestore.collection(this.collectionName).doc<Note>(id).snapshotChanges()
.pipe(
map(a => {
const id = a.payload.id;
const data = a.payload.data();
return { id, ...data };
})
);
}
getNotes(): Observable<Note[]> {
return this.firestore.collection<Note>(this.collectionName).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const id = a.payload.doc.id;
const data = a.payload.doc.data();
return { id, ...data };
});
})
);
}
updateNote(id: string, note: Note): Promise<void> {
return this.firestore.collection(this.collectionName).doc<Note>(id).update(note);
}
deleteNote(id: string): Promise<void> {
return this.firestore.collection(this.collectionName).doc(id).delete();
}
}
We are now ready to use this firebase service to perform CRUD operations from different ionic pages.
Creating a List Page to list all the Notes
Let’s create a new Ionic Page to list all the notes from Firebase.
ionic g page list-note
Add notes collection field to hold notes.
notes: Observable<Note[]>;
Add FirebaseService as dependency injection to the List note component class
constructor(private noteService: FirebaseService) {
}
Initialize notes field.
ngOnInit() {
this.notes = this.noteService.getNotes();
}
Following is the complete List Note Page component class.
import { Component, OnInit } from '@angular/core';
import { FirebaseService } from '../services/firebase.service';
import { Note } from '../models/note';
import { Observable } from 'rxjs';
@Component({
selector: 'app-list-note',
templateUrl: './list-note.page.html',
styleUrls: ['./list-note.page.scss'],
})
export class ListNotePage implements OnInit {
notes: Observable<Note[]>;
constructor(private noteService: FirebaseService) {
}
ngOnInit() {
this.notes = this.noteService.getNotes();
}
}
Update List Note template with following.
<ion-list>
<ion-item [routerLink]="['/display-note', item.id]" *ngFor="let item of (notes | async)">
<ion-label>
<h2>{{item.title}}</h2>
<p>{{item.content}}</p>
</ion-label>
</ion-item>
</ion-list>
Add List Note Component to home page template. i.e. home.page.html
<ion-header [translucent]="true">
<ion-toolbar color="primary">
<ion-title>
Notes
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<app-list-note></app-list-note>
</ion-content>
Similarly we will create other pages for Get, Create, Update and Delete operations.
Creating Display Page to show single record from Firebase
Create a Display Page component.
ionic g page list-note
Display Note component class
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FirebaseService } from '../services/firebase.service';
import { Note } from '../models/note';
@Component({
selector: 'app-display-note',
templateUrl: './display-note.page.html',
styleUrls: ['./display-note.page.scss'],
})
export class DisplayNotePage implements OnInit {
note: Note;
constructor(private router: Router, private activatedRoute: ActivatedRoute, private noteService: FirebaseService) {
this.note = new Note();
}
ngOnInit() {
this.noteService.getNote(this.activatedRoute.snapshot.params.id)
.subscribe(data => {
this.note = data;
});
}
}
Display note template
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{note.title}}</ion-title>
<ion-buttons slot="end">
<ion-button color="primary" [routerLink]="['/edit-note', note.id]">
<ion-icon name="create-outline"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>{{note.content}}</p>
</ion-content>
Creating Create Page to add a new record in Firebase
Create a Create Note Component.
ionic g page create-note
Update Create Note Component class with the following.
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { FirebaseService } from '../services/firebase.service';
import { Note } from '../models/note';
@Component({
selector: 'app-create-note',
templateUrl: './create-note.page.html',
styleUrls: ['./create-note.page.scss'],
})
export class CreateNotePage implements OnInit {
noteForm : FormGroup;
constructor(private formBuilder: FormBuilder, private router: Router, private noteService: FirebaseService) {
this.noteForm = this.formBuilder.group({
title: new FormControl('', Validators.required),
content: new FormControl('', Validators.required)
});
}
ngOnInit() {
}
onSubmit() {
const note: Note = Object.assign({}, this.noteForm.value);
this.noteService.addNote(note)
.then(_ => {
this.router.navigate(['/home']);
});
}
onReset(){
this.noteForm.reset();
}
}
Create Note Template
<ion-header>
<ion-toolbar color="primary">
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Add Note</ion-title>
<ion-buttons slot="end" tooltip="Reset form" (click)="onReset()">
<ion-icon name="refresh-outline"></ion-icon>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<form [formGroup]="noteForm" (ngSubmit)="onSubmit()" novalidate>
<ion-item>
<ion-input placeholder="Enter notes title" autofocus=true formControlName="title"></ion-input>
</ion-item>
<ion-item>
<ion-textarea placeholder="Enter your notes here..." rows="10" formControlName="content"></ion-textarea>
</ion-item>
<ion-button color="primary" class="ion-float-left" type="submit" [disabled] = !noteForm.valid>Save</ion-button>
</form>
</ion-content>
Update home.page.html to add a Fab Add button.

<ion-header [translucent]="true">
<ion-toolbar color="primary">
<ion-title>
Notes
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<app-list-note></app-list-note>
<!-- fab placed to the top end -->
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button [routerLink]="['/create-note']">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
Update create-note.module.ts to add ReactiveFormsModule.
We are using Reactive Forms for forms in Angular.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { CreateNotePageRoutingModule } from './create-note-routing.module';
import { CreateNotePage } from './create-note.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
IonicModule,
CreateNotePageRoutingModule
],
declarations: [CreateNotePage]
})
export class CreateNotePageModule {}
Creating Update Page to update a record in the Firebase.
Create Update Note page component.
ionic g page update-note
Update Note Component Class
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { FirebaseService } from '../services/firebase.service';
import { Note } from '../models/note';
@Component({
selector: 'app-edit-note',
templateUrl: './edit-note.page.html',
styleUrls: ['./edit-note.page.scss'],
})
export class EditNotePage implements OnInit {
id: string='';
noteForm : FormGroup;
constructor(private formBuilder: FormBuilder, private router: Router, private activatedRoute: ActivatedRoute, private noteService: FirebaseService) {
this.noteForm = this.formBuilder.group({
title: new FormControl('', Validators.required),
content: new FormControl('', Validators.required)
});
}
ngOnInit() {
this.id= this.activatedRoute.snapshot.paramMap.get("id");
this.noteService.getNote(this.activatedRoute.snapshot.paramMap.get("id"))
.subscribe(data => {
this.noteForm = this.formBuilder.group({
title: new FormControl(data.title, Validators.required),
content: new FormControl(data.content, Validators.required)
});
});
}
onSubmit() {
const note: Note = Object.assign({}, this.noteForm.value);
this.noteService.updateNote(this.id, note)
.then(()=>{
this.router.navigate(['/home']);
});
}
}
Update Note Template
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Edit Note</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<form [formGroup]="noteForm" (ngSubmit)="onSubmit()" novalidate>
<ion-item>
<ion-input placeholder="Enter notes title" autofocus=true formControlName="title"></ion-input>
</ion-item>
<ion-item>
<ion-textarea placeholder="Enter your notes here..." rows="10" formControlName="content"></ion-textarea>
</ion-item>
<ion-button color="primary" class="ion-float-left" type="submit" [disabled] = !noteForm.valid>Save</ion-button>
</form>
</ion-content>
Update create-note.module.ts to add ReactiveFormsModule
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EditNotePageRoutingModule } from './edit-note-routing.module';
import { EditNotePage } from './edit-note.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
IonicModule,
EditNotePageRoutingModule
],
declarations: [EditNotePage]
})
export class EditNotePageModule {}
Deleting a Record Using Delete Operation
To Delete note we will add a Delete button on Display Note Page.

<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>{{note.title}}</ion-title>
<ion-buttons slot="end">
<ion-button color="primary" [routerLink]="['/edit-note', note.id]">
<ion-icon name="create-outline"></ion-icon>
</ion-button>
<ion-button color="danger" (click)="onDelete()">
<ion-icon name="trash-outline"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<p>{{note.content}}</p>
</ion-content>
Update display-note.page.ts Component Class for delete method.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FirebaseService } from '../services/firebase.service';
import { Note } from '../models/note';
@Component({
selector: 'app-display-note',
templateUrl: './display-note.page.html',
styleUrls: ['./display-note.page.scss'],
})
export class DisplayNotePage implements OnInit {
note: Note;
constructor(private router: Router, private activatedRoute: ActivatedRoute, private noteService: FirebaseService) {
this.note = new Note();
}
ngOnInit() {
this.noteService.getNote(this.activatedRoute.snapshot.params.id)
.subscribe(data => {
this.note = data;
});
}
onDelete(){
this.noteService.deleteNote(this.note.id)
.then(()=>{
this.router.navigate(['/home']);
});
}
}
Conclusion
In this post we learned how to perform the CRUD operations in Firestore database inside Firebase using Ionic 5 application which was created using Angular 12.
We started with setting up the Firebase project to get firestore database settings. Then we created the ionic 5 application using ionic CLI and then added support for all of the Read, Create, Update and Delete operations.
Please leave your feedback or comment if you are facing any issue.