For all the developers who have been searching for a robust platform for building mobile and web applications faster, you can think about Firebase. Firebase is a Backend-as-a-Service — BaaS — that started and grew up into a next-generation app-development platform on Google Cloud Platform. Implementation of the authentication system with Firebase in web and mobile apps is very easy.
Today, I am going to create a sample application to show the CRUD operation in Firebase with Angular 8 Application.
If you don't have an understanding about the connection of Angular application, Read the article my previous article on Firebase How to connect Firebase with Angular 8 Application from scratch
Let's Get Started
I assume the Angular 8 application has already created and connected with Firebase with the above link provided. So, I am skipping these steps.
Step 1: Create a Service File
Now, I am going to create a service file that will have logic to make request to firebase for all the operation we will have in the Angular 8 app.
Run below command in Angular CLI to generate authentication service file:
import { Injectable } from '@angular/core';
import { Document } from '../_model/document';
import { AngularFirestore } from "@angular/fire/firestore";
@Injectable({
providedIn: 'root'
})
export class DocumentService {
constructor(private firestore: AngularFirestore) {}
/* Add Document */
AddDocument(document: Document) {
return new Promise<any>((resolve, reject) => {
this.firestore.collection("documents").add(document)
.then(res => {
resolve(res);
}, err => reject(err));
});
}
// /* Get Document */
GetDocument(id: string) {
return this.firestore.collection("documents").doc(id).snapshotChanges();
}
/* Get Document list */
GetDocumentList() {
return this.firestore.collection("documents").snapshotChanges();
}
// /* Update Document */
updateDocument(userKey, value){
return this.firestore.collection('documents').doc(userKey).set(value);
}
// /* Delete Document */
DeleteDocument(data) {
return this.firestore.collection("documents").doc(data.payload.doc.id)
.delete();
}
}
Also, add the service file in app.module.ts file
Step 2: Create Components for Listing, Add, Edit tasks
ng g c components/add-document
ng g c components/edit-document
ng g c components/document-list
Step 3: Update add-document component files
Put below code inside the add-document.ts file
import { Component, OnInit } from '@angular/core';
import { DocumentService } from './../../services/document.service';
import { FormGroup, FormControl, Validators, NgForm } from "@angular/forms";
import { Router } from '@angular/router';
@Component({
selector: 'app-add-document',
templateUrl: './add-document.component.html',
styleUrls: ['./add-document.component.css']
})
export class AddDocumentComponent implements OnInit {
addDocumentForm:FormGroup;
constructor(
private _documentService : DocumentService,
private router : Router
) { }
ngOnInit() {
this.addDocumentForm = new FormGroup ({
title: new FormControl (null, [Validators.required, Validators.maxLength(200)]),
description: new FormControl (null, [Validators.required, Validators.maxLength(200)]),
author: new FormControl (null, [Validators.required, Validators.maxLength(200)])
})
}
submitDocument(form):void{
this._documentService.AddDocument(form.value);
this.router.navigate(['document-list']);
}
}
In the above file, We have a basic component with a reactive form and a submitDocument function to handle the submit request from the form and make the request to firebase accordingly.
Update add-document.ts file
<section>
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3 form-wrapper">
<h3 class="text-center">Add Document</h3>
<form [formGroup]="addDocumentForm" novalidate>
<div class="form-group">
<label for="title">Title:</label>
<input type="text" name="title" class="form-control" id="title" formControlName="title">
</div>
<div class="form-group">
<label for="description">Description:</label>
<input type="text" name="description" class="form-control" id="description" formControlName="description">
</div>
<div class="form-group">
<label for="author">Author:</label>
<input type="text" class="form-control" id="author" name="author" formControlName="author">
</div>
<button type="submit" [disabled]="!addDocumentForm.valid" class="btn btn-primary"
(click)="submitDocument(addDocumentForm)">Submit</button>
</form>
</div>
</div>
</div>
</section>
In the above file, We have a form with three input fields and a submit button.
Step 4: Update edit-document component files
Put below code in the edit-document.ts file
import { Component, OnInit } from '@angular/core';
import { DocumentService } from './../../services/document.service';
import { FormGroup, FormControl, Validators, NgForm } from "@angular/forms";
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-edit-document',
templateUrl: './edit-document.component.html',
styleUrls: ['./edit-document.component.css']
})
export class EditDocumentComponent implements OnInit {
editDocumentForm:FormGroup;
id:string;
constructor(
private _document : DocumentService,
private route : ActivatedRoute,
private router : Router
) { }
ngOnInit() {
this.editDocumentForm = new FormGroup ({
title: new FormControl (null, [Validators.required, Validators.maxLength(200)]),
description: new FormControl (null, [Validators.required, Validators.maxLength(200)]),
author: new FormControl (null, [Validators.required, Validators.maxLength(200)])
});
this.id = this.route.snapshot.paramMap.get("id");
this.getDocument();
}
getDocument() {
this._document.GetDocument(this.id)
.subscribe(res => {
this.editDocumentForm.controls['title'].setValue (res.payload.data()['title']);
this.editDocumentForm.controls['description'].setValue (res.payload.data()['description']);
this.editDocumentForm.controls['author'].setValue (res.payload.data()['author']);
});
}
submitDocument(form){
this._document.updateDocument(this.id, form.value)
.then(
res => {
this.router.navigate(['document-list']);
}
)
}
}
Update edit-document file
<section>
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3 form-wrapper">
<h3 class="text-center">Edit Document</h3>
<form [formGroup]="editDocumentForm" novalidate>
<div class="form-group">
<label for="title">Title:</label>
<input type="text" name="title" class="form-control" id="title" formControlName="title">
</div>
<div class="form-group">
<label for="description">Description:</label>
<input type="text" name="description" class="form-control" id="description" formControlName="description">
</div>
<div class="form-group">
<label for="author">Author:</label>
<input type="text" class="form-control" id="author" name="author" formControlName="author">
</div>
<button type="submit" [disabled]="!editDocumentForm.valid" class="btn btn-primary"
(click)="submitDocument(editDocumentForm)">Submit</button>
</form>
</div>
</div>
</div>
</section>
Step 5: Update document-list component files
Add below code in the document-list.component.ts file
import { Component, OnInit } from '@angular/core';
import { DocumentService } from './../../services/document.service';
@Component({
selector: 'app-document-list',
templateUrl: './document-list.component.html',
styleUrls: ['./document-list.component.css']
})
export class DocumentListComponent implements OnInit {
documents;
id;
constructor(
private _documentService : DocumentService,
) { }
ngOnInit() {
this.getDocumentList();
}
getDocumentList = () =>
this._documentService
.GetDocumentList()
.subscribe(res => {
this.documents = res;
});
deleteDocument = data => this._documentService.DeleteDocument(data);
}
Add below code in the document-list.component.html file
<section>
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3 form-wrapper">
<h3 class="text-center">Document List</h3>
<table>
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Author</th>
<td></td>
</tr>
</thead>
<tbody>
<tr *ngFor="let document of documents">
<td>{{ document.payload.doc.data().title }}</td>
<td>{{ document.payload.doc.data().description }}</td>
<td>{{ document.payload.doc.data().author }}</td>
<td>
<button class="btn btn-primary" [routerLink]="['/edit-document/', document.payload.doc.id]"><i class="fa fa-pencil"></i></button>
<button class="btn btn-primary" (click)="deleteDocument(document)"><i class="fa fa-trash"></i></button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
Step 6: Create routes to serve different components on different routes.
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddDocumentComponent } from './components/add-document/add-document.component';
import { EditDocumentComponent } from './components/edit-document/edit-document.component';
import { DocumentListComponent } from './components/document-list/document-list.component';
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'add-document' },
{ path: 'add-document', component: AddDocumentComponent },
{ path: 'edit-document/:id', component: EditDocumentComponent },
{ path: 'document-list', component: DocumentListComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Step 7: Update app.module.ts file
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
/*Firebase */
import { AngularFireModule } from '@angular/fire';
import { AngularFirestoreModule } from "@angular/fire/firestore";
import { environment } from 'src/environments/environment';
/*Components */
import { AddDocumentComponent } from './components/add-document/add-document.component';
import { EditDocumentComponent } from './components/edit-document/edit-document.component';
import { DocumentListComponent } from './components/document-list/document-list.component';
/*Service */
import { DocumentService } from './services/document.service';
@NgModule({
declarations: [
AppComponent,
AddDocumentComponent,
EditDocumentComponent,
DocumentListComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFirestoreModule
],
providers: [DocumentService],
bootstrap: [AppComponent]
})
export class AppModule { }
In the above file, you can see the need firebase packages, created service file and components file bootstrapped here.
Step 8: Run the app
Run the above app with below command:
Now you can check the app on the browser.
In the article, I have not much explained the libraries/package used in the demo. I would suggest you to read about these on its official sites.
Conclusion
We have successfully created the Angular Firebase CRUD app after following some steps.
If you are new to Angular 8 then find Angular Sample Projects to start the app for enterprise-level application
Let me know your thoughts over email demo.jsonworld@gmail.com. I would love to hear them and If you like this article, share with your friends.
Thank You!