Nesse artigo você vai aprender como criar seu primeiro aplicativo com
o armazenamento de banco de dados com Firebase e Angular.
Para saber mais sobre o Firebase acesse o site clicando aqui.
O que é o Firebase Realtime Database?
O Firebase Realtime Database é um banco de dados online. Os dados são armazenados em formato JSON e sincronizados em tempo real com todos os clientes conectados independente da plataforma (Android, iOS, Web).
Realtime Database fornece uma linguagem de regras declarativas que permite que você defina como os dados devem ser estruturados, como devem ser indexados e quando podem ser lidos e gravados. Por padrão, o acesso de leitura e gravação ao seu banco de dados é restrito, exceto para usuários autenticados, portanto, você deve configurar as regras antes de começar
O Firebase Realtime Database permite você a criar um conjunto de regras para definir quando os dados podem ser lidos e gravados e também como indexar os dados para facilitar nas consultas.
Por padrão, as regras permitem que qualquer usuário identificado pode ler e gravar dados. Para saber mais sobre como criar regras e indexar os dados você pode clicar aqui. Na aplicação que será construída de exemplo vamos utilizar as regras e o index abaixo:
{ "rules": { ".read": "true", ".write": "true", "tasks": { ".indexOn": ["done"] } } }
Criando uma aplicação de exemplo
Seguindo os passos abaixo você vai conseguir criar seu primeiro aplicativo com o Firebase Realtime Database. Como exemplo será criado um aplicativo de cadastro de tarefas.
O que você vai aprender?
- Criar uma aplicação com Angular 2 do zero.
- Configurar a apliação para integrar com o Firebase.
- Incluir, alterar, excluir e consultar dados no Firebase Realtime Database
Pré-requisitos:
- Ter instalado o nodejs.
- Ter uma conta do Firebase. Crie uma clicando aqui.
1 – Criando um projeto no Firebase
Criar um projeto no Firebase é muito simples. Seguindo os passos abaixo você irá criar um projeto em poucos minutos.
1 – Na pagina principal do Firebase, apos efetuar o login com sua conta do Google, clique em “Ir para o console“.
2 – Agora clique no botão “Criar novo projeto”
3 – No modal que se abrir, informe o “nome do projeto”, a “região” e clique em “criar projeto”.
4 – Quando o processo terminar, clique no nome do projeto para ser redirecionado para o console do projeto.
2 – Criando um projeto com Angular
Criar um projeto do zero com Angular é muito simples basta seguir o passo a passo abaixo:
1 – Baixe o Angular 2 QuickStart direto do repositório do Angular no GitHub clicando aqui. Ou use os comandos abaixo:
git clone https://github.com/angular/quickstart.git nomedoseuprojeto cd nomedoseuprojeto npm install
2 – Delete os arquivos que não são necessários (opcional):
for /f %i in (non-essential-files.txt) do del %i /F /S /Q rd .git /s /q rd e2e /s /q
3 – Para ver o projeto em funcionamento no navegador utilize o comando abaixo:
npm start
3 – Adicionando Firebase ao projeto
Para manipular o Firebase vamos utilizar a biblioteca oficial do Angular que é a AngularFire2.
Vamos também utilizar o npm para instalar as dependências com o Firebase e o AngularFire2.
Na publicação desse artigo as versões estáveis das bibliotecas do Firebase e AngularFire2 são “3.4.0” e “2.0.0-beta.8” respectivamente.
1 – Abra o aquivo package.json e adicione as linhas abaixo em “dependencies”.
"firebase": "3.4.0", "angularfire2": "2.0.0-beta.8"
2 – Abra o arquivo src/systemjs.config.js
Em map adicione as linhas abaixo:
'angularfire2': 'npm:angularfire2/bundles', 'firebase': 'npm:firebase'
Em packages adicione as linhas abaixo:
angularfire2: { main: 'angularfire2.umd.js' }, firebase: { main: 'firebase.js' }
3 – Navegue até a pasta do projeto e execute o comando abaixo para instalar as dependências na versões especificadas:
npm install
4 – Abra o arquivo src/app/app.module.ts e adicione o provider e as configurações do Firebase:
Você pode pegar suas configurações do Firebase na pagina inicial do projeto clicando no botão “Adicionar o Firebase ao seu aplicativo da Web”.
Arquivo src/app/app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { AngularFireModule } from 'angularfire2'; export const firebaseConfig = { apiKey: '[SUA-APIKEY]', authDomain: '[SEU-AUTH-DOMAIN]', databaseURL: '[SUA-DATABASE-URL]', storageBucket: '[SEU-STORAGE-BUCKET]', messagingSenderId: '[SEU-MESSAGING-SENDER-ID]' }; @NgModule({ imports: [ BrowserModule, AngularFireModule.initializeApp(firebaseConfig) ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
4 – Criando o componente para criar tarefas
1 – Criar uma classe de nome task.model.ts no caminho src/app/todo/ para colocar quais serão as propriedades de uma tarefa. Para uma tarefa precisamos de um titulo, descrição, uma flag para informar se está ou não concluída e a propriedade $key que será o identificador do registro no Firebase.
Arquivo src/app/todo/task.model.ts
export class Task { done: boolean; title: string; description: string; $key: string; }
2 – Agora vamos criar o serviço que vai fazer as operações de incluir, alterar, excluir e consultar os registros no Firebase.
Para isso vamos criar um arquivo de nome task.service.ts no caminho src/app/todo/
import { Injectable } from '@angular/core'; import { Task } from './task.model'; import { AngularFire, FirebaseListObservable } from 'angularfire2'; @Injectable() export class TaskService { angularfire: AngularFire; items: FirebaseListObservable<any>; constructor(af: AngularFire) { this.angularfire = af; } getAll() { // Buscando todos os itens no no "/task" this.items = this.angularfire.database.list('/tasks'); return this.items; } getAllCompleted() { // Buscando todos os itens que estão completos this.items = this.angularfire.database.list('/tasks', { query: { orderByChild: 'done', // filtrando pelo campo "done" equalTo: true // e que tanha o valor true } }); return this.items; } getAllOpened() { // Buscando todos os itens que estão em aberto this.items = this.angularfire.database.list('/tasks', { query: { orderByChild: 'done', // filtrando pelo campo "done" equalTo: false // e que tanha o valor false } }); return this.items; } add(task: Task) { // Adicionando uma nova tarefa. // Toda nova tarefa é gravada como em aberto por padrão. task.done = false; // Adicionando o item na lista de itens. // Como essa lista é carregada antes, automaticamente o angularfire2 // identifica a mudança na lista e inclui o item novo. this.items.push(task); } update(task: Task) { // Atualizando o item na lista. // Para isso passamos por parametro qual é o id do item no Firebase // e quais são os novos valores. this.items.update(task.$key, task); } save(task: Task) { // Metodo criado para facilitar a inclusão/alteração e um item. // Verifico se o item tem o Id para saber se é uma inclusão ou alteração. if (task.$key == null) { this.add(task); } else { this.update(task); } } remove(task: Task) { // Removendo um item da lista this.items.remove(task.$key); } toggleDone(task: Task) { // Marcando uma tarefa como concluída ou em aberto. task.done = !task.done; this.update(task); } }
3 – Agora vamos criar o componente que ira exibir o formulário para inclusão/alteração e os itens na tela. Para isso vamos criar o arquivo task.component.ts no caminho src/app/todo/
import { Component, OnInit } from '@angular/core'; import { Task } from './task.model'; import { TaskService } from './task.service'; import { FirebaseListObservable } from 'angularfire2'; @Component({ selector: 'todo-task', templateUrl: 'app/todo/task.component.html' }) export class TaskComponent implements OnInit { tasks: FirebaseListObservable<any>; task: Task; constructor(private taskService: TaskService) { this.task = new Task(); } ngOnInit() { // Ao iniciar o componente, busco todos os items já existentes no Firebase. this.tasks = this.taskService.getAll(); } saveTask() { // Se os campos do formulario foram preenchidos, adiciono a nova tarefa. if (this.task.title && this.task.description) { this.taskService.save(this.task); this.task = new Task(); } } editTask(task: Task) { // Ao clicar 2x em um item da lista e vai para o formulário para ser editado. this.task = task; } remove(task: Task) { this.taskService.remove(task); } toggleDone(task: Task) { this.taskService.toggleDone(task); } filterTasks(filter: number) { // Filtrando os itens switch (filter) { case 1: // Todos this.tasks = this.taskService.getAll(); break; case 2: // Todas tarefas em aberto this.tasks = this.taskService.getAllOpened(); break; case 3: // Todas tarefas concluídas this.tasks = this.taskService.getAllCompleted(); break; } } }
4 – E agora o arquivo HTML que será o template do componente. Para isso vamos criar o arquivo task.component.html no caminho src/app/todo/
<h1 class="text-center">ToDo - Fábrica de Código</h1> <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> <div class="panel panel-primary"> <div class="panel-body"> <form role="form" novalidate> <div class="form-group"> <label for="title">Título</label> <input [(ngModel)]="task.title" type="text" class="form-control" id="title" name="title" placeholder="O que você deseja fazer?" required /> </div> <div class="form-group"> <label for="description">Descrição</label> <input [(ngModel)]="task.description" type="text" class="form-control" id="description" name="description" placeholder="Uma pequena descrição" required /> </div> <button type="submit" class="btn btn-primary" (click)="saveTask()">Salvar</button> </form> </div> </div> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Tarefas</h3> </div> <div class="panel-body"> <div class="bs-callout" *ngFor="let task of tasks | async" [ngClass]="{ 'bs-callout-primary': !task.done }"> <div class="row"> <div class="col-xs-1 col-sm-1 col-md-1 col-lg-1"> <input type="checkbox" [checked]="task.done" (click)="toggleDone(task)" /> </div> <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10" (dblclick)="editTask(task)"> <h4 [ngClass]="{ 'item-done': task.done }">{{task.title}}</h4> <div [ngClass]="{ 'item-done': task.done }">{{task.description}}</div> <div>{{ task.$value }}</div> </div> <div class="col-xs-1 col-sm-1 col-md-1 col-lg-1 remove"> <a (click)="remove(task)"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> </a> </div> </div> </div> </div> <div class="panel-footer"> <label class="radio-inline"> <input (click)="filterTasks(1)" type="radio" name="statusTask" id="todos" value="1" checked > Todas </label> <label class="radio-inline"> <input (click)="filterTasks(2)" type="radio" name="statusTask" id="ativos" value="2"> Ativas </label> <label class="radio-inline"> <input (click)="filterTasks(3)" type="radio" name="statusTask" id="completas" value="2"> Completas </label> </div> </div> </div> </div>
Atenção para listar os itens é necessário usar o Pipe async do angular para garantir que sempre vamos listar os valores mais atuais do Firebase.
5 – Agora é necessário modificar o arquivo src/app/app.component.ts e adicionar o serviço TaskService, que foi criado acima, como um provider.
import { Component } from '@angular/core'; import { TaskService } from './todo/task.service'; @Component({ selector: 'todo-app', template: `<todo-task></todo-task>`, providers: [ TaskService ] }) export class AppComponent { }
6 – E por fim precisamos editar o arquivo src/app/app.module.ts novamente e incluir as referencias para o FormsModule do angular e o componente TaskComponent criado acima.
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { AngularFireModule } from 'angularfire2'; import { FormsModule } from '@angular/forms'; import { TaskComponent } from './todo/task.component'; export const firebaseConfig = { apiKey: 'AIzaSyCz7kugPPNI24kcVjjNTO4HiGpqKDvn8J0', authDomain: 'todofabricadecodigo-c6949.firebaseapp.com', databaseURL: 'https://todofabricadecodigo-c6949.firebaseio.com', storageBucket: 'todofabricadecodigo-c6949.appspot.com', messagingSenderId: '902107944829' }; @NgModule({ imports: [ BrowserModule, FormsModule, AngularFireModule.initializeApp(firebaseConfig) ], declarations: [ AppComponent, TaskComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
Conclusão
É muito simples fazer uma integração entre o Angular e o Firebase e apesar o AngularFire2 ser uma biblioteca ainda em fase beta, ela fornesse bastante recurso para que você consiga trabalhar com o Firebase.
Referencias:
- Documetação do Angular: https://angular.io/docs/ts/latest/
- Documentação do Firebase para web: https://firebase.google.com/docs/web/setup
- Documentação do AngularFire2: https://github.com/angular/angularfire2
- Projeto criado nesse tutorial: https://github.com/fabricadecodigo/angular2-examples/tree/master/ToDoAppWithFirebase
Eu espero que esse tutorial tenha sido útil para você. Qualquer dúvida
deixe seu comentário abaixo.