10 de agosto de 2022 • 15 min de leitura
Como instalar, configurar e utilizar o Firebase em aplicações React Native
Nesse artigo aprenderemos como instalar, configurar e utilizar o Firebase em nossos apps React Native, além disso, aprenderemos também como utilizar o Firebase Auth e Firestore Database.
Após começar a utilizar o Firebase em alguns projetos pessoais e profissionais, vejo como essas bibliotecas podem nos auxiliar e empoderar nossos aplicativos, principalmente quando não temos a estrutura de um backend, ou quando queremos ter um login ou banco de dados de forma mais simplificada por exemplo.
Por isso, decidi criar esse design/projeto exclusivamente para aprendermos a configurar o Firebase e seus pacotes em nossos projetos, além de explicar como utilizar o Auth para criarmos login com e-mail e senha, e o firestore para o armazenamento dos dados dos users.
O primeiro passo será iniciarmos o nosso projeto, com isso, resolvi criá-lo com o React Native CLI visto que o Expo esta com alguns problemas na ultima versão do SDK 65, principalmente relacionado a dependência @types/react
onde ele entra em um loop dizendo que você não instalou a dependência, mesmo já estando instalada.
Para startar nosso projeto com TypeScript, rodaremos o seguinte comando:
npx react-native init nomeProjeto --template react-native-template-typescript
Como o projeto foi criado a partir da CLI, para rodar em nossos emuladores é necessário realizar o build do app no Android Studio
e XCode
ou rodando yarn android
e yarn ios
.
💡 NIT: sempre que crio um projeto, eu também crio a pasta referente a ele no Github, assim consigo versionar e não perder o que tenho progredido no projeto.
Projeto criado e buildado com sucesso ✅
Depois de criado e buildado o projeto, o próximo passo que realizo é iniciar as instalações do Firebase. Porém, antes de iniciar, você conhece a ferramenta?
O que é o Firebase?
É uma plataforma do Google que auxilia no desenvolvimento de aplicativos web e/ou mobile, de forma rápida e simples.
O Firebase é um BaaS (Backend as a Service), ou seja, provê a estrutura e o backend sem ter que desenvolver o backend de forma manual, além disso, oferece várias soluções como: armazenamento de arquivos, autenticação de usuários, banco de dados, analytics, feature-flags...
Para saber mais sobre a ferramenta, basta acessar as duas documentações disponíveis, a do react native firebase https://rnfirebase.io/ e a do próprio Firebase https://firebase.google.com/docs .
Quais são as vantagens do Firebase?
- Possui uma versão gratuita e muito completa por sinal
- Escalável
- Possui suporte para diversos tipos de plataformas (iOS, Android, JavaScript e C++) utilizando a mesma API
- Reduz o tempo de desenvolvimento já que entrega o backend pronto
- Possui fácil implementação
1. Criando um projeto no Firebase Console
-
Antes de iniciarmos a instalação de pacotes no código, necessitamos acessar o Console do Firebase para criar um novo projeto. Você pode utilizar uma conta Google para conectar-se, ou criar uma nova conta gratuita caso não tenha, e para isso, basta clicar em "Começar”. https://firebase.google.com/
-
Após realizarmos o login no Console do Firebase, clique em "+ Adicionar projeto"
- Em seguida, digite um nome para o seu projeto e clique no botão continuar.
- Na próxima etapa, você pode deixar o Google Analytics ativado ou não e clicar no botão continuar.
- Em Configurar o Google Analytics, selecione a opção "Default Account for Firebase" e clique no botão "Criar Projeto".
-
Pronto! Agora é só esperar o projeto ser criado. 🎉
2. Instalação do React Native Firebase App
Agora, vamos instalar o módulo React Native Firebase App. Pois, é ele quem faz a conexão da nossa aplicação com o Firebase.
Então, execute a instalação na raiz do projeto:
# Com npm
npm install --save @react-native-firebase/app
# Com Yarn
yarn add @react-native-firebase/app
3. Configuração no Android
Para realizar a configuração no Android, primeiramente necessitamos ir no console do Firebase para adicionar um novo aplicativo Android. Então, clique no ícone do Android.
-
Para registrar nosso app Android no primeiro passo, realizaremos as instruções abaixo e posteriormente clicaremos em Registar app para passarmos para as próximas etapas.
a. Para encontrar o nome do pacote Android, basta acessarmos em nosso código o arquivo MainActivity.java e o nome estará na primeira linha do arquivo.
b. Em apelido do app podemos colocar Android
c. No campo certificado de assinatura SHA-1 não necessitaremos nesse exemplo, pois ele é obrigatório apenas em alguns cenários específicos, mas caso necessite gerar o certificado, digite no prompt o código abaixo e o certificado será gerado.cd android bash ./gradlew signinReport
Serão geradas várias chaves, mas a necessária para este campo é
Variant: debugAndroidTest - SHA1
-
Na próxima etapa, faremos o download do arquivo de configuração que é o google-services.json e clicar em Próxima.
a. Iremos baixá-lo e inserí-lo em nosso código dentro de/android/app/
-
Posteriormente adicionaremos o SDK do Firebase em nosso aplicativo, ou seja, configuraremos o código nativo que irá conectar a nossa aplicação com o Firebase.
a. Primeiro vamos dentro do arquivo/android/build.gradle
e adicionaremos dentro debuildscript
:buildscript { repositories { // Check that you have the following line (if not, add it): google() // Google's Maven repository } dependencies { ... // Add this line classpath("com.google.gms:google-services:4.3.13") } } allprojects { ... repositories { // Check that you have the following line (if not, add it): google() // Google's Maven repository ... } }
b. Posteriormente, iremos adicionar dentro do
arquivo /android/app/build.gradle
o seguinte trecho:apply plugin: 'com.android.application' // Add this line apply plugin: 'com.google.gms.google-services' dependencies { // Import the Firebase BoM if you choose utilize analytics implementation platform('com.google.firebase:firebase-bom:30.3.1') // Add the dependency for the Firebase SDK for Google Analytics // When using the BoM, don't specify versions in Firebase dependencies implementation 'com.google.firebase:firebase-analytics' }
4. Configuração no iOS
Para realizar a configuração no iOS segue o mesmo padrão do Android, primeiramente necessitamos ir no console do Firebase, clicar em Adicionar app e então, clicaremos no ícone do iOS+.
-
Conforme configuramos no Android, preencheremos os campos abaixo e em seguida clicaremos em Registrar app para seguirmos para as próximas etapas.
a. Para encontrarmos o nome do
ID do pacote Apple
necessitamos abrir nosso projeto noXCode
clicar em cima do nome do projeto e assim será aberto ao lado do nome, do lado direito, mais detalhes do projeto, e dentro da aba General conseguimos ver dentro de Bundle Identifier o nome que utilizaremos dentro doID do pacote Apple
b. No Apelido do app coloquei o nome de iOS
c. No campo Código da App Store você pode adicionar caso já tenha a conta da appStoreConect, mas é totalmente opcional -
Na próxima etapa, iremos realizar o download do arquivo de configuração que é o GoogleService-Info.plist e clicar em Próxima.
a. Iremos baixá-lo e para inserí-lo dentro do projeto, abriremos novamente oXCode
→ clicaremos em cima do nome do projeto, apertar o botão direito do mouse →Add Files to "nome do projeto
b. Selecionaremos o arquivo baixado e clicaremos em Add
-
Agora a partir da etapa 3 da documentação, não seguiremos exatamente como está descrito. Nesse passo, é solicitado que adicionemos o SDK do Firebase, mas todas as vezes que tentei realizar esse passo, o SDK de alguma forma fez o meu projeto ter alguns bugs, então preferi não instalá-lo, mas esteja a vontade para fazê-lo, se desejar. Ou seja, esse passo eu pulo.
-
Na etapa de adicionar o código de inicialização, também faremos um pouco diferente do que é visualizado, porque nosso código iOS está em C++ e as opções exibidas são apenas para
SwiftUI
,Swift
eObjective-C
.
a. Para permitir que o Firebase use as credenciais no iOS, abra dentro do código o arquivo/ios/{projectName}/AppDelegate.m
e adicionaremos a seguinte linha na parte superior do arquivo, logo abaixo de#import "AppDelegate.h"
:#import "AppDelegate.h" #import "Firebase.h" #import "FirebaseCore.h"
b. Ainda nesse arquivo, adicionaremos o seguinte trecho de código:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Add this config [FIRApp configure]; return YES; }
5. Instalação das bibliotecas do Firebase
Agora que nosso Firebase está instalado e devidamente configurado, instalaremos as bibliotecas que utilizaremos nesse projeto de login.
-
A primeira lib a ser instalada será o Cloud Firestore, que é um banco de dados de documentos NoSQL. É escalonável e focado em desenvolvimento de aplicações móveis e web.
Principais benefícios
- Flexibilidade
- Consultas expressivas
- Atualizações em tempo real
- Podemos utilizar a sincronização de dados para atualizá-los em qualquer dispositivo conectado
- Suporte off-line
- Armazena em cache os dados ativamente utilizados pelo aplicativo
- Projetado para escalar
Assim, para podermos utilizá-lo necessitamos instalar a biblioteca da seguinte forma:
yarn add @react-native-firebase/firestore
-
A segunda biblioteca que instalaremos será a de Auth para podermos dar vida as telas de login com e-mail e senha. Para instalá-la necessitamos rodar:
yarn add @react-native-firebase/auth
Pronto, agora sim, nosso Firebase está instalado, configurado, e com as bibliotecas necessárias também instaladas. Mas agora necessitamos rodar o
pod install
em nossa pasta iOS e posteriormente buildar novamente o projeto em nossos emuladores Android e iOS, visto que fizemos configurações em códigos nativos.cd ios/ && pod install
Pode ser que ocorra um erro o rodar o pod install parecido com o abaixo:
The Swift pod FirebaseCoreInternal depends upon GoogleUtilities, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers! globally in your Podfile, or specify :modular_headers => true for particular dependencies.
Basicamente temos que permitir vincular bibliotecas estáticas Swift, como oFirebaseCoreInternal
e para isso adicionaremos o seguinte comando em nosso arquivo Podfile:pod 'Firebase', :modular_headers => true pod 'FirebaseCore', :modular_headers => true pod 'FirebaseCoreInternal', :modular_headers => true pod 'GoogleUtilities', :modular_headers => true
E depois buildar novamente o projeto nos emuladores Android e iOS, via prompt ou via Android Studio e XCode.
yarn ios yarn android
Agora sim, tudo pronto para começarmos a utilizá-lo em nosso código.
Para iniciarmos a utilização das bibliotecas que instalamos do Firebase, criei o projeto Water Reminder no meu Github, que pode ser acessado pelo link: https://github.com/ildaneta/water-reminderSe vocês quiserem, podem clonar o projeto a partir da branch
feature/screens
, assim, toda a parte de telas, componentes e navegações já estarão configuradas, e será possível implementar as telas de SignIn, SignUp e Recovery password com o que aprenderemos em seguida.Branch: https://github.com/ildaneta/water-reminder/tree/feature/screens
Utilizando o Auth e Cloud Firestore
-
Para iniciarmos a utilizar o Auth do Firebase, iremos novamente até o console https://console.firebase.google.com e no menu superior esquerdo clicaremos em Criação → Authentication
Logo em seguida, clicaremos em Vamos começar → escolher a opção de E-mail/senha
Ativaremos a primeira opção e logo após, clicar em Salvar.
-
Configuramos nosso Auth no console do Firebase, agora criaremos nosso Cloud Firestore, ou seja, nosso banco de dados, que salvará os dados dos users. Para isso, iremos novamente no menu superior esquerdo, clicaremos em Firestore Database e logo após em Criar banco de dados.
Escolha o modo de produção → Avançar, logo após, o local do Cloud Firestore e Ativar
Assim que nosso banco de dados estiver criado, iremos dentro de Regras e apagaremos a parte
: if false
; do lado de,write
, em seguida, clicar em Publicar, porque assim, salvaremos dados no banco de dados, mesmo quando o usuário ainda não estiver logado.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: // if false; // apagar } } }
-
O próximo passo é configurar uma coleção, que seria o mesmo de uma tabela, nesse caso, será nossa tabela de users. Daremos o nome da coleção e clicaremos em Próxima.
Para criar uma collection pelo Firebase é necessário inserir um id do documento, nesse caso, podemos clicar em Código automático e Salvar assim nossa collection estará criada.
- Agora chegou o momento do código.
Para essa aplicação, como tudo está relacionado a parte de login, criei um hook chamadouseAuth
onde estarão todas as funções necessárias para o login funcionar corretamente, que serão: signUp(responsável por criar um usuário), signIn(responsável por realizar o login), singOut(responsável por deslogar o usuário), recoveryPassword(responsável por resetar a senha do user via e-mail), isLoading(retornará se está havendo um carregamento), e user(retorna o id e username do usuário). -
Criando um Usuário com Firebase Auth e adicionando-o dentro da collection de Users do Firebase Firestore.
Para criar o usuário com o auth é necessário chamar o método do auth.createUserWithEmailAndPassword(email, password)
passando o email e senha digitada pelo user. Após isso, guardo os dados no firestore, chamando o métodofirestore()
, para salvar os dados na collection de users, utilizo o método.collection('users')
passando o nome da collection.Aqui tem um detalhe importante, pois para adicionar dados em uma collection posso utilizar duas formas, uma com o método
.add()
, assim criamos um novo dado na collection com um id aleatório criado pelo Firebase, mas nesse cenário eu precisava que o id do documento da collection fosse igual ao id do user criado no auth, com isso, ao adicionar eu utilizo o método.doc(uid)
passando o id da conta do usuário dentro do auth, e chamo o método.set()
passando o id do user e o nome de cadastro que serão armazenados na collection de users do firestore.const signUp = async ({username, email, password}: SignUpData) => { if (!username || !email || !password) { return Alert.alert( 'SignUp', 'Enter username, e-mail and password to create your account.', ); } if (password.length < 6) { return Alert.alert( 'SignUp', 'Password cannot be less than 6 characters.', ); } try { setIsLoading(true); await auth() .createUserWithEmailAndPassword(email, password) .then(account => { const {uid} = account.user; firestore() .collection('users') .doc(uid) .set({ id: uid, username, }) .then(() => { Alert.alert('SignUp', 'Account created with sucess!', [ { text: 'Ok', onPress: () => navigation.navigate('SignIn'), }, ]); }); setIsLoading(false); }) .catch(error => { const {code} = error; if (code === 'auth/email-already-in-use') { return Alert.alert('SignUp', 'E-mail is already in use'); } setIsLoading(false); }) .finally(() => { setIsLoading(false); }); } catch (error) {} };
Basicamente são esses os passos para criar um usuário com as duas libs, o restante do código são apenas algumas verificações e redirecionamentos que realizo.
-
Realizar o login de um usuário já cadastrado na base dados do auth e firestore
Os passos para realizar o login são bem parecidos ao de criar um novo user, o que mudam são os métodos utilizados.
No auth, ao invés de utilizar o
.createUserWithEmailAndPassword()
para criar, utilizaremos o.signInWithEmailAndPassword(email, password)
para realizar o login, e para trazer do firestore esse user já cadastrado, utilizamos o método.get()
passando antes qual a collection que iremos buscar o dado e qual o id do documento que será recuperado.Outro passo que realizo no signIn é salvar os dados do usuário que são o id e o nome dentro do
AsyncStorage
assim consigo verificar se o usuário já está logado para que não precise passar novamente pela tela de signIn.const signIn = async ({email, password}: SignInData) => { if (!email || !password) { return Alert.alert('SignIn', 'E-mail and password is required.'); } setIsLoading(true); auth() .signInWithEmailAndPassword(email, password) .then(response => { const {uid} = response.user; firestore() .collection('users') .doc(uid) .get() .then(async profile => { const {id, username} = profile.data() as IUser; if (profile.exists) { const userData = { id, username, }; setUser(userData); AsyncStorage.setItem(USER_COLLECTION, JSON.stringify(userData)); navigation.navigate('Home'); } setIsLoading(false); }); }) .catch(error => { const {code} = error; if (code === 'auth/wrong-password') { return Alert.alert( 'SignIn', 'The password is invalid or the user does not have a password.', ); } if (code === 'auth/user-not-found') { Alert.alert( 'SignIn', 'There is no user record corresponding to this e-mail.', ); } }) .finally(() => setIsLoading(false)); };
-
Realizar a recuperação de senha do user
Para enviar um e-mail de recuperação de senha e assim o usuário poder modificá-la, utilizamos o método do auth.sendPasswordResetEmail(email)
, esse é bem simples, porque o firebase cuida de todo o restante, que seria enviar o e-mail e salvar a nova senha cadastrada. No código abaixo além de chamar o método para recuperar a senha, apresento alertas em caso de sucesso e erro.const recoveryPassword = async ({email}: RecoveryPasswordData) => { if (!email) { return Alert.alert('Recovery password', 'E-mail is required.'); } await auth() .sendPasswordResetEmail(email) .then(() => { Alert.alert( 'Recovery password', 'We have sent a link to your email to reset your password.', [ { text: 'Ok', onPress: () => navigation.navigate('SignIn'), }, ], ); }) .catch(error => { const {code} = error; if (code === 'auth/user-not-found') { Alert.alert( 'Recovery password', 'It was not possible to send the password reset to your e-mail, because the e-mail you entered was not registered.', ); } }); };
-
Deslogar o user da aplicação
Por fim, mas não menos importante, seria o passo de realizar o logout do usuário do aplicativo, e para isso chamamos o método do auth.signOut()
. Como eu também salvo noAsyncStorage
os dados do user quando ele loga, nesse momento eu também os removo e navego novamente para a tela de SignIn.const signOut = async () => { setIsLoading(true); await auth().signOut(); await AsyncStorage.removeItem(USER_COLLECTION); setUser(null); setIsLoading(false); navigation.navigate('SignIn'); };
Basicamente são esses os passos que temos que realizar para ter a solução de login completa utilizando o firebase.
Lembrando que vocês podem acompanhar todo o progresso / implementação do aplicativo pelo projeto no Github: https://github.com/ildaneta/water-reminder
Além disso, esse projeto é open source, ou seja, o código é aberto e vocês podem utilizá-lo a vontade, além disso, é uma ótima oportunidade para realizar contribuições, ou seja, vocês podem fazer esse app criar vida, enviar solicitações de pull request para mim, inserir testes, enfim, colocar todos os conhecimentos em prática e ainda contribuir em um projeto da comunidade.
Espero que tenham gostado do artigo, apesar de bem grande, tentei explicar no máximo de detalhes possíveis como instalar, configurar e utilizar o Firebase, que ja é uma das minhas libs favoritas, e que no começo tive alguns probleminhas para realizar a instalação inicial, que para mim é o mais complexo.
Até o próximo artigo pessoal! 🫶🏻