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.

Ionic 5 | 4 Operações CRUD usando Firebase com Firestore NoSQL Database Tutorial em Ionic Angular Application
Ionic 5 | 4 Operações CRUD usando Firebase com Firestore NoSQL Database Tutorial em Ionic Angular Application

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>
        &nbsp;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
Ionic 5 | 4 Operações CRUD usando Firebase com Firestore NoSQL Database Tutorial em Ionic Angular Application

https://github.com/ipsjolly/FreakyJolly.com/tree/master/ionic5/ionic-firebase-crud-operations