Firebase com Angula 17
Introdução:
Recentemente tenho focado muito em aprender novas ferramentas de desenvolvimento front-end como Angular e React, e pra evitar aquele trabalho de abrir uma API com Express, ASP.NET ou qualquer outra tecnologia o Firebase tem me sido bem útil para criar aplicações reais sem me preocupar muito com gerenciar banco de dados, autenticação, buckets e etc.
Com as atualizações do Angular 17 a forma com o qual você implementa o firebase no seu projeto mudou completamente, e infelizmente a maioria dos conteúdos e documentações que pesquisei para tentar me ajudar a fazer essa integração estão desatualizadas. Então minha proposta é escrever esse artigo para ajudar pessoas como eu que gostariam de implementar o Firebase com o Angular 17. Chega de enrolar e vamos para o código.
✏️ OBS: Vou pressupor que você já criou e configurou um projeto no firebase e está tendo dificuldade somente na integração com o AngularAdicionando as dependências do Firebase no seu app:
O primeiro passo é adicionar o firebase e os serviços que você irá utlizar nas configurações do seu app, para isso você vai precisar adicionar o @angular/fire
no seu projeto:
npm install @angular/fire
Com as dependências instaladas já podemos prover o firebase para a nossa aplicação. Nas versões anteriores do Angular bastava você ir no arquivo app.module.ts
e configura-lo lá porém, no Angular 17 o app.module.ts
não existe mais e toda a configuração agora é feita pelo app.config.ts
:
Nesse exemplo vamos inicializar o FirebaseApp, Firestore, Auth e Storage:
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
//Firebase Dependencies
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { provideAuth, getAuth } from '@angular/fire/auth'
import { provideStorage, getStorage } from '@angular/fire/storage'
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideClientHydration(),
provideHttpClient(),
//Provendo dependencias:
importProvidersFrom(
provideFirebaseApp(() => initializeApp(FIREBASE_CONFIG))
provideAuth(() => getAuth())
provideFirestore(() => getFirestore())
provideStorage(()=> getStorage())
)
]
};
PS: Lembre-se de substituir o FIREBASE_CONFIG
pelas configurações do seu projeto.
Basicamente, agora você tem que prover os serviços para o seu app para que eles sejam reconhecidos globalmente no contexto da sua aplicação.
Uso do Firestore:
Para exemplificar o uso do Firestore, vamos fazer aquele service de um CRUD de posts bem simples:
import { Injectable } from '@angular/core';
import { CollectionReference, Firestore, collection } from '@angular/fire/firestore';
import { addDoc, getDocs, updateDoc, deleteDoc } from 'firebase/firestore';
@Injectable({
providedIn: 'root'
})
export class CrudService {
constructor(private firestore: Firestore) { }
postsCollection = collection(this.firestore, 'posts') as CollectionReference<Post>
createPost = async (post: Post) => {
const doc = await addDoc(this.postsCollection , post);
return doc;
}
getPost = async (postId: string) => {
const docRef = doc(this.firestore, "posts", postId);
const docSnap = await getDoc(docRef);
return docSnap.data()
}
updatePost = async (post: Post) => {
const docRef = doc(this.firestore, "posts", postId);
updateDoc(docRef, post);
}
deletePost = async (postId: string) => {
const docRef = doc(this.firestore, "posts", postId);
deleteDoc(docRef);
}
}
Basicamente depois de injetar a dependência do Firestore instanciamos a collection que queremos manipular e fazemos os métodos baseados nela ou nas referencias de um documento especifico.
Uso da Autenticação:
Para exemplificar a autenticação vamos criar um service básico com as funções signIn()
(Login) e signUp()
(Registro) numa autenticação por e-mail e senha simples:
import { Injectable } from '@angular/core';
import { Auth, signInWithEmailAndPassword, createUserWithEmailAndPassword } from '@angular/fire/auth';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor(private auth: Auth) { }
signIn = async (email: string, password: string) => {
try {
const result = await signInWithEmailAndPassword(this.auth, email, password);
console.log(result);
}catch (err) {
console.error(err);
}
}
signUp = async (email: string, password: string) => {
try {
const result = await createUserWithEmailAndPassword(this.auth, email, password);
console.log(result);
}catch (err) {
console.error(err);
}
}
}
Basicamente, fazemos a injeção de dependência do Auth e usamos os métodos signInWithEmailAndPassword()
para o login e o createUserWithEmailAndPassword()
para o registro.
Uso do Storage:
Para exemplificar o uso do Storage vou mostrar uma função de upload de uma foto:
import { Storage, getDownloadURL, ref, uploadBytes } from '@angular/fire/storage';
@Injectable({
providedIn: 'root'
})
export class StorageService {
constructor(private storage: Storage) { }
uploadFile = async (file) => {
const path = `pictures/${file.name}`;
const storageReference = ref(this.storage, path);
const uploadTask = await uploadBytes(storageRef, file);
const url = await getDownloadURL(uploadTask.ref);
console.log(url);
}
}
Após fazermos a injeção de dependência do Storage temos que configurar a referência ao storage que queremos subir os arquivos, e isso é feito através do ref()
, que recebe a dependência e o caminho do storage. Agora para subir um arquivo (nesse caso uma imagem) utilizamos o método assíncrono uploadBytes()
que recebe mais uma vez a dependência e o arquivo que será importado. Por ultimo obtemos a url da imagem que já está na web através do getDownloadURL()
.
É isso, espero ter te ajudado na sua jornada de aprendizado! Vai lá nas minhas redes: