Executando verificação de segurança...
3

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 Angular

Adicionando 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:

Carregando publicação patrocinada...