In this tutorial, I will show you how to build Angular 10 CRUD App with Firebase Realtime Database that uses AngularFireDatabase service.
Related Posts:
– Angular 10 Firestore CRUD with AngularFireStore
– Angular 10 Firebase Storage: File Upload/Display/Delete example
– Angular 10 CRUD Application example with Web API
– Angular 10 Form Validation example (Reactive Forms)
Newer versions:
– Angular 11 Firebase CRUD example
– Angular 12 Firebase CRUD example
– Angular 13 Firebase CRUD example
– Angular 14 Firebase CRUD example
– Angular 15 Firebase CRUD example
– Angular 16 Firebase CRUD example
– Angular 17 Firebase CRUD example
Contents
- Angular 10 Firebase CRUD Overview
- AngularFireDatabase service
- Technology
- Setup the Firebase Project
- Setup Angular 10 Project
- Project Structure
- Integrate Firebase into Angular 10 App
- Define Model Class
- Create Data Service
- Component for creating Object
- Component for List of Objects
- Component for Object details
- Define Routes for App Routing Module
- Add Navbar and Router View to Angular Firebase App
- Run & Check
- Conclusion
- Further Reading
- Source Code
Angular 10 Firebase CRUD Overview
We’re gonna build an Angular 10 Firebase App using @angular/fire library in which:
- Each Tutorial has key, title, description, published status.
- We can create, retrieve, update, delete Tutorials.
Here are the screenshots:
– Create a new Tutorial:

Firebase Realtime Database right after the Operation:

– Retrieve all Tutorials with details when clicking on a Tutorial:

– Change status to Published/Pending using Publish/UnPublish button:

– Update the Tutorial details with Update button:

If you want to implement Reactive Form Validation, please visit:
Angular 10 Form Validation example (Reactive Forms)
– Delete the Tutorial using Delete button:

– Delete all Tutorials with Remove All button:

AngularFireDatabase service
@angular/fire provides AngularFireDatabase service that allows us to work with the Realtime Database. It’s an efficient, low-latency solution for apps that require synced states across clients in realtime.
import { AngularFireDatabase} from '@angular/fire/database'; export class TutorialService { constructor(private db: AngularFireDatabase) { } } AngularFireDatabase for Object
The AngularFireObject is a service for manipulating and streaming object data which is created via AngularFireDatabase service.
– Create an object binding/ Retrieve:
tutorial: AngularFireObject<any>; // db: AngularFireDatabase this.tutorial = db.object('tutorial'); // or Observable<any> tutorial = db.object('tutorial').valueChanges(); – Create/Update an object:
const tutRef = db.object('tutorial'); // set() for destructive updates tutRef.set({ title: 'zkoder Tutorial'}); – Update an object:
const tutRef= db.object('tutorial'); tutRef.update({ url: 'bezkoder.com/zkoder-tutorial' }); – Delete an object:
const tutRef = db.object('tutorial'); tutRef.remove(); AngularFireDatabase for List
Through the AngularFireDatabase service, we can create AngularFireList service that helps to synchronize data as lists.
– Create a list binding/ Retrieve:
+ Get an Observable of data as a synchronized array of JSON objects without snapshot metadata.
tutorials: Observable<any[]>; // db: AngularFireDatabase this.tutorials = db.list('tutorials').valueChanges(); + Get an Observable of data as a synchronized array of AngularFireAction<DatabaseSnapshot>[] with metadata (the underyling DatabaseReference and snapshot key):
tutorials: Observable<any[]>; this.tutorials = db.list('tutorials').snapshotChanges(); – Create a List and push a new object:
const tutorialsRef = db.list('tutorials'); tutorialsRef.push({ title: 'zkoder Tutorial', url: 'bezkoder.com/zkoder-tutorial' }); – Update a List:
+ destructive update using set(): delete everything currently in place, then save the new value
const tutorialsRef = db.list('tutorials'); tutorialsRef.set('key', { title: 'zkoder Tut#1', url: 'bezkoder.com/zkoder-tut-1' }); + non-destructive update using update(): only updates the specified values
const tutorialsRef = db.list('tutorials'); tutorialsRef.update('key', { title: 'zkoder new Tut#1' }); – Delete an object in List:
const tutorialsRef = db.list('tutorials'); tutorialsRef.remove('key'); – Delete entire List:
const tutorialsRef = db.list('tutorials'); tutorialsRef.remove(); Technology
- Angular 10
- firebase 7
- @angular/fire 6
- rxjs 6
Setup the Firebase Project
Go to Firebase Console, login with your Google Account, then click on Add Project.
You will see the window like this:

Enter Project name, set Project Id and click on Continue.
Turn off Enable Google Analytics for this project, then click Create Project.
Now, browser turns into following view:

If you don’t see it, just choose Project Overview.
Click on Web App, you will see:

Set the nickname and choose Register App for next step.

Save the information for later usage.
Choose Database in the left (list of Firebase features) -> Realtime Database -> Create Database.

In this tutorial, we don’t implement Authentication, so let’s choose test mode:

Or if you come from another situation, just open Tab Rules, then change .read and .write values to true.
Setup Angular 10 Project
Let’s open cmd and use Angular CLI to create a new Angular Project as following command:
ng new Angular10Crud ? Would you like to add Angular routing? Yes ? Which stylesheet format would you like to use? CSS We also need to generate some Components and Services:
ng g s services/tutorial ng g c components/add-tutorial ng g c components/tutorial-details ng g c components/tutorials-list Now you can see that our project directory structure looks like this.
Project Structure

Let me explain it briefly.
– environment.ts configures information to connect with Firebase Project.
– models/tutorial.ts defines data model class.
– services/tutorial.service.ts exports TutorialService that uses @angular/fire‘s AngularFireDatabase to interact with Firebase Database.
– There are 3 components that uses TutorialService:
add-tutorialfor creating new itemtutorials-listcontains list of items, parent oftutorial-detailstutorial-detailsshows item details
– app-routing.module.ts defines routes for each component.
– app.component contains router view and navigation bar.
– app.module.ts declares Angular components and imports necessary environment & modules.
Integrate Firebase into Angular 10 App
First run the command: npm install firebase @angular/fire.
Open src/environments/environment.ts, add Firebase configuration that we have saved when Popup window was shown:
export const environment = { production: false, firebase: { apiKey: 'xxx', authDomain: 'angular-10-crud-db.firebaseapp.com', databaseURL: 'https://angular-10-crud-db.firebaseio.com', projectId: 'angular-10-crud-db', storageBucket: 'angular-10-crud-db.appspot.com', messagingSenderId: 'xxx', appId: '1:xxx:web:xxx' } }; Open app.module.ts, import AngularFireModule, AngularFireDatabaseModule and environment:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AngularFireModule } from '@angular/fire'; import { AngularFireDatabaseModule } from '@angular/fire/database'; import { environment } from '../environments/environment'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AddTutorialComponent } from './components/add-tutorial/add-tutorial.component'; import { TutorialDetailsComponent } from './components/tutorial-details/tutorial-details.component'; import { TutorialsListComponent } from './components/tutorials-list/tutorials-list.component'; @NgModule({ declarations: [ AppComponent, AddTutorialComponent, TutorialDetailsComponent, TutorialsListComponent ], imports: [ BrowserModule, AppRoutingModule, FormsModule, AngularFireModule.initializeApp(environment.firebase), AngularFireDatabaseModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } Define Model Class
Let’s create Tutorial class with 4 fields: key, title, description, published.
models/tutorial.ts
export default class Tutorial { key: string; title: string; description: number; published = false; } Create Data Service
This service will use AngularFireDatabase and AngularFireList to interact with Firebase Realtime Database. It contains necessary functions for CRUD operations.
services/tutorial.service.ts
import { Injectable } from '@angular/core'; import { AngularFireDatabase, AngularFireList } from '@angular/fire/database'; import Tutorial from '../models/tutorial'; @Injectable({ providedIn: 'root' }) export class TutorialService { private dbPath = '/tutorials'; tutorialsRef: AngularFireList<Tutorial> = null; constructor(private db: AngularFireDatabase) { this.tutorialsRef = db.list(this.dbPath); } getAll(): AngularFireList<Tutorial> { return this.tutorialsRef; } create(tutorial: Tutorial): any { return this.tutorialsRef.push(tutorial); } update(key: string, value: any): Promise<void> { return this.tutorialsRef.update(key, value); } delete(key: string): Promise<void> { return this.tutorialsRef.remove(key); } deleteAll(): Promise<void> { return this.tutorialsRef.remove(); } } Component for creating Object
his component has a Form to submit new Tutorial with 2 fields: title & description. It calls TutorialService.create() method.
components/add-tutorial/add-tutorial.component.ts
import { Component, OnInit } from '@angular/core'; import { TutorialService } from 'src/app/services/tutorial.service'; import Tutorial from 'src/app/models/tutorial'; @Component({ selector: 'app-add-tutorial', templateUrl: './add-tutorial.component.html', styleUrls: ['./add-tutorial.component.css'] }) export class AddTutorialComponent implements OnInit { tutorial: Tutorial = new Tutorial(); submitted = false; constructor(private tutorialService: TutorialService) { } ngOnInit(): void { } saveTutorial(): void { this.tutorialService.create(this.tutorial).then(() => { console.log('Created new item successfully!'); this.submitted = true; }); } newTutorial(): void { this.submitted = false; this.tutorial = new Tutorial(); } } components/add-tutorial/add-tutorial.component.html
<div class="submit-form"> <div *ngIf="!submitted"> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" required [(ngModel)]="tutorial.title" name="title" /> </div> <div class="form-group"> <label for="description">Description</label> <input class="form-control" id="description" required [(ngModel)]="tutorial.description" name="description" /> </div> <button (click)="saveTutorial()" class="btn btn-success">Submit</button> </div> <div *ngIf="submitted"> <h4>You submitted successfully!</h4> <button class="btn btn-success" (click)="newTutorial()">Add</button> </div> </div> Component for List of Objects
This component calls TutorialService methods:
getAll()deleteAll()
components/tutorials-list/tutorials-list.component.ts
import { Component, OnInit } from '@angular/core'; import { TutorialService } from 'src/app/services/tutorial.service'; import { map } from 'rxjs/operators'; @Component({ selector: 'app-tutorials-list', templateUrl: './tutorials-list.component.html', styleUrls: ['./tutorials-list.component.css'] }) export class TutorialsListComponent implements OnInit { tutorials: any; currentTutorial = null; currentIndex = -1; title = ''; constructor(private tutorialService: TutorialService) { } ngOnInit(): void { this.retrieveTutorials(); } refreshList(): void { this.currentTutorial = null; this.currentIndex = -1; this.retrieveTutorials(); } retrieveTutorials(): void { this.tutorialService.getAll().snapshotChanges().pipe( map(changes => changes.map(c => ({ key: c.payload.key, ...c.payload.val() }) ) ) ).subscribe(data => { this.tutorials = data; }); } setActiveTutorial(tutorial, index): void { this.currentTutorial = tutorial; this.currentIndex = index; } removeAllTutorials(): void { this.tutorialService.deleteAll() .then(() => this.refreshList()) .catch(err => console.log(err)); } } In the code above, to get the key of each item, we use snapshotChanges() with RxJS map() operator. This key is unique and important for update operation.
We also have refreshList() function for every time delete operation is done.
components/tutorials-list/tutorials-list.component.html
<div class="list row"> <div class="col-md-6"> <h4>Tutorials List</h4> <ul class="list-group"> <li class="list-group-item" *ngFor="let tutorial of tutorials; let i = index" [class.active]="i == currentIndex" (click)="setActiveTutorial(tutorial, i)" > {{ tutorial.title }} </li> </ul> <button class="m-3 btn btn-sm btn-danger" (click)="removeAllTutorials()"> Remove All </button> </div> <div class="col-md-6"> <div *ngIf="currentTutorial"> <app-tutorial-details (refreshList)="refreshList()" [tutorial]="currentTutorial" ></app-tutorial-details> </div> <div *ngIf="!currentTutorial"> <br /> <p>Please click on a Tutorial...</p> </div> </div> </div> You can see that when we click on any item, setActiveTutorial() function will be invoked to change current active Tutorial, which data is passed to tutorial-details component.
Component for Object details
This component is the child of tutorial-list. It bind tutorial data and emit refreshList event to the parent.
For getting update, delete the Tutorial, we’re gonna use two TutorialService methods:
update()delete()
components/tutorial-details/tutorial-details.component.ts
import { Component, OnInit, Input, OnChanges, Output, EventEmitter } from '@angular/core'; import { TutorialService } from 'src/app/services/tutorial.service'; import Tutorial from 'src/app/models/tutorial'; @Component({ selector: 'app-tutorial-details', templateUrl: './tutorial-details.component.html', styleUrls: ['./tutorial-details.component.css'] }) export class TutorialDetailsComponent implements OnInit, OnChanges { @Input() tutorial: Tutorial; @Output() refreshList: EventEmitter<any> = new EventEmitter(); currentTutorial: Tutorial = null; message = ''; constructor(private tutorialService: TutorialService) { } ngOnInit(): void { this.message = ''; } ngOnChanges(): void { this.message = ''; this.currentTutorial = { ...this.tutorial }; } updatePublished(status): void { this.tutorialService.update(this.currentTutorial.key, { published: status }) .then(() => { this.currentTutorial.published = status; this.message = 'The status was updated successfully!'; }) .catch(err => console.log(err)); } updateTutorial(): void { const data = { title: this.currentTutorial.title, description: this.currentTutorial.description }; this.tutorialService.update(this.currentTutorial.key, data) .then(() => this.message = 'The tutorial was updated successfully!') .catch(err => console.log(err)); } deleteTutorial(): void { this.tutorialService.delete(this.currentTutorial.key) .then(() => { this.refreshList.emit(); this.message = 'The tutorial was updated successfully!'; }) .catch(err => console.log(err)); } } components/tutorial-details/tutorial-details.component.html
<div *ngIf="currentTutorial" class="edit-form"> <h4>Tutorial</h4> <form> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" [(ngModel)]="currentTutorial.title" name="title" /> </div> <div class="form-group"> <label for="description">Description</label> <input type="text" class="form-control" id="description" [(ngModel)]="currentTutorial.description" name="description" /> </div> <div class="form-group"> <label><strong>Status:</strong></label> {{ currentTutorial.published ? "Published" : "Pending" }} </div> </form> <button class="badge badge-primary mr-2" *ngIf="currentTutorial.published" (click)="updatePublished(false)" > UnPublish </button> <button *ngIf="!currentTutorial.published" class="badge badge-primary mr-2" (click)="updatePublished(true)" > Publish </button> <button class="badge badge-danger mr-2" (click)="deleteTutorial()"> Delete </button> <button type="submit" class="badge badge-success" (click)="updateTutorial()"> Update </button> <p>{{ message }}</p> </div> <div *ngIf="!currentTutorial"> <br /> <p>Cannot access this Tutorial...</p> </div> Define Routes for App Routing Module
There are 2 main routes:
/addforadd-tutorialcomponent/tutorialsfortutorials-listcomponent
app-routing.module.ts
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { TutorialsListComponent } from './components/tutorials-list/tutorials-list.component'; import { AddTutorialComponent } from './components/add-tutorial/add-tutorial.component'; const routes: Routes = [ { path: '', redirectTo: 'tutorials', pathMatch: 'full' }, { path: 'tutorials', component: TutorialsListComponent }, { path: 'add', component: AddTutorialComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } Let’s open src/app.component.html, this App component is the root container for our application, it will contain a nav element.
<div> <nav class="navbar navbar-expand navbar-dark bg-dark"> <a href="#" class="navbar-brand">bezKoder</a> <div class="navbar-nav mr-auto"> <li class="nav-item"> <a routerLink="tutorials" class="nav-link">Tutorials</a> </li> <li class="nav-item"> <a routerLink="add" class="nav-link">Add</a> </li> </div> </nav> <div class="container mt-3"> <h2>{{ title }}</h2> <router-outlet></router-outlet> </div> </div> Run & Check
You can run this App with command: ng serve.
Open browser with url: http://localhost:4200/ and check the result.
Conclusion
Today we’ve built an Angular 10 Firebase CRUD Application successfully working with Realtime Database using AngularFireDatabase from @angular/fire library. Now we can display, modify, delete object and list at ease.
If you want to use Firestore instead, please visit:
Angular 10 Firestore CRUD with AngularFireStore
Or File upload:
Firebase Storage + Angular 10: File Upload/Display/Delete example
You can also find how to create Angular HTTP Client for working with Restful API in:
Angular 10 CRUD Application example with Web API
Or implement Reactive Form Validation:
Angular 10 Form Validation example (Reactive Forms)
Happy learning, see you again!
Further Reading
- Angular Template Syntax
- Angular Router Guide
- https://www.npmjs.com/package/@angular/fire
- Firebase Web Get Started
Other versions:
– Angular 8 Firebase CRUD example
– Angular 11 Firebase CRUD example
– Angular 12 Firebase CRUD example
– Angular 13 Firebase CRUD example
– Angular 14 Firebase CRUD example
– Angular 15 Firebase CRUD example
Fullstack CRUD Application:
- Angular 10 + Node.js Express + MySQL example
- Angular 10 + Node.js Express + MongoDB example
- Angular 10 + Node.js Express + PostgreSQL example
- Angular 10 + Spring Boot + MySQL example
- Angular 10 + Spring Boot + PostgreSQL example
- Angular 10 + Spring Boot + MongoDB example
- Angular 10 + Django example
Source Code
You can find the complete source code for this tutorial on Github.

Amazing Angular 10 and Firebase tutorial!
This is mostly great. Everything works except for the update function. it is looking for a ‘key’ in the document but it never gets populated. I am trying to figure out how to populate the ‘key’ field with the auto-generated document ID but so far no luck. Do you have any idea how to do this?
How do I create the model folder on cli? I followed the instructions but the models folder was not in the file structure.
Hi, you can created the folder manually, or use the command:
ng g class models/tutorial.Thank you for this tutorial. It help me a lot to start with Angular.