CRUD com Ionic e Firebase
Atualizar Ionic CLI
Primeiro passo é atualizar o Ionic com npm para atualizar a ferramenta Ionic CLI pra versão mais recente.
npm install -g @ionic/cli
Criar uma aplicação Ionic
Escolha a opção blank
ionic start "NomedoApp" --type=angular
em seguida, vá para a pasta raiz do aplicativo
cd "NomedoApp"
Crie um projeto Firebase
1 – Visite o Firebase e clique em Primeiros passos se ainda não tiver criado uma conta.
2 – Clique em “Adicionar projeto” e insira as informações relacionadas ao aplicativo, clique em “Criar Projeto”
3 – Em seguida, clique no ícone “Web App” para obter o texto de configuração com as informações keys para aplicativo, que será adicionada em nosso Ionic para nos comunicarmos com serviços relacionados a este projeto.
4 – O próximo passo é ativar o serviço Firestore Database no projeto Firebase
Na barra lateral esquerda, selecione o Banco de dados e clique no botão Criar. Isso habilitará o serviço de banco de dados para nosso aplicativo em Ionic. Agora estamos prontos para conectar nosso aplicativo com o projeto do Firebase
Adicionar credenciais do Firebase ao Ionic
Agora precisamos adicionar as credenciais do projeto Firebase no aplicativo Ionic para criar uma conexão. Abra o arquivo que está localizado na “NomedoApp”/src/environment/enviroment.ts
Para isso podemos usar o editor de texto de sua distribuição Linux ou de sua distribuição Windows ou Mac, atualize conforme abaixo.
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]"
}
Instale as dependências do Firebase no Ionic
Para integrar os serviços do Firebase, é necessária a biblioteca angularfire
Também precisaremos instalar o firebase pacote que vai interagir com o angularfire
npm install firebase @angular/fire --save
Importar módulos do Firebase
Necessária a importação do AngularFireModule e também o AngularFirestoneModule para usar o serviço de banco de dados Firestone NoSQL
O arquivo app.module.ts ficará assim
// app.module.ts import {NgModule} de '@ angular / core'; import {BrowserModule} de '@ angular / platform-browser'; import {RouteReuseStrategy} de '@ angular / router'; importar {IonicModule, IonicRouteStrategy} de '@ ionic / angular'; importar {SplashScreen} de '@ ionic-native / splash-screen / ngx'; importar {StatusBar} de '@ ionic-native / status-bar / ngx'; importar {AppComponent} de './app.component'; importar {AppRoutingModule} de './app-routing.module'; importar {ambiente} de 'src / ambientes / ambiente'; importar {AngularFireModule} de '@ angular / fire'; import {AngularFirestoreModule} de '@ angular / fire / firestore'; declarações: [AppComponent], entryComponents: [], importações: [ BrowserModule, IonicModule.forRoot (), AppRoutingModule, AngularFireModule.initializeApp (environment.firebase), AngularFirestoreModule ], provedores: [ StatusBar, SplashStrategyScreenCluse, {fornecer: IonicRouteStrategy} ], bootstrap: [AppComponent] }) export class AppModule {}
Criar um service com metódos para Firestone
ionic generate service services/firebase
Atualizar Firebase Service com metódos CRUD
Substitua o código abaixo no arquivo firebase.service.ts
// 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();
}
}
No serviço acima, importe a AngularFirestone classe para usar métodos. A seguir todos métodos que realizam operações de Students coleta e manipulação de documentos.
create_student(): Criar um novo registro na coleção especificada chamando o add()
read_students(): Método de chamada snapshotChanges() que obterá registro e também se inscreverá para obter atualizações
update_students(): O doc() metódo usa o nome da coleção com id do documento para atualizar o registro, então o update() metódo é chamado para salvar o documento.
delete_student(): Como o update, o método doc() leva o nome da coleção com id para delete().
Adicionar formulário e lista do aluno
Temos um formulçário com [formGroup] para validação de formulário reativo e (ngSubmit) manipulador de eventos. Há três controles de entrada para Name, Age e Adress ter formControlName propriedade em cada para obter o valor da validação
A lista de Alunos é mostrada no ion-card componente. Isso é ter blocos condicionais para o modo de edição.
<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>
Atualizar home.page.ts
// 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;
}
}
Os dados serão do interface tipo StudentData definido na aula
interface StudentData {
Name: string;
Age: number;
Address: string;
}
Em seguida, crie um grupo do formulário usando o FormBuilder e defina a validação necessária.
this.studentForm = this.fb.group({
Name: ['', [Validators.required]],
Age: ['', [Validators.required]],
Address: ['', [Validators.required]]
})
Na página init, chamaremos o read_student() método de serviço para buscar lista de alunos existente salvos na coleção do Firebase. Portanto, sempre que houver uma alteração nos dados do Firestone durante as operações CRUD, as alterações serão atualizadas em tempo real, conforme chamamos o snapshotChanges() na Students coleção.
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'],
};
})
});
O CreateRecord() método assumirá valores de formulário para enviar ao Firestore chamando o creat_student(). Com sucesso, estamos redefinindo o formulário.
CreateRecord() {
this.firebaseService.create_student(this.studentForm.value)
.then(resp => {
//Reset form
this.studentForm.reset();
})
.catch(error => {
console.log(error);
});
}
Ao clinar no ícone Editar, estamos definindo os valores reais em campos temporário usando o EditRecord() para que possamos mostrar os valores reais se o usuário clicar no botão Cancelar
EditRecord(record) {
record.isEdit = true;
record.EditName = record.Name;
record.EditAge = record.Age;
record.EditAddress = record.Address;
}
Ao clicar no botão de atualização no modo de edição, os valores alterados serão atualizados chamando o update_student() de services.
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;
}
Import ReactiveFormModule para FormValidation
Como estamos usando a abordagem do Formulário Reativo para validar o formulário para a criação de Aluno, precisamos imporatr o ReactiveFormsModule no arquivo home.module.ts conforme mostrado abaixo
// home.module.ts import {NgModule} de '@ angular / core'; import {CommonModule} de '@ angular / common'; importar {IonicModule} de '@ ionic / angular'; import {FormsModule, ReactiveFormsModule} de '@ angular / forms'; importar {HomePage} de './home.page'; import {HomePageRoutingModule} de './home-routing.module'; @NgModule ({ importações: [ CommonModule, FormsModule, ReactiveFormsModule, IonicModule, HomePageRoutingModule ], declarações: [HomePage] }) exportar classe HomePageModule {}
Agora pode executar o aplicativo
ionic serve --open
https://github.com/ipsjolly/FreakyJolly.com/tree/master/ionic5/ionic-firebase-crud-operations