Pesquisa de site

Autenticando usuários com Firebase e React


Descubra como o Firebase pode facilitar a integração de usuários.

O Firebase fornece serviços de autenticação que permitem registrar e fazer login de usuários com facilidade. Você pode usar e-mail, senhas, números de telefone e provedores de identidade como Google e Facebook.

Neste tutorial, você aprenderá como usar o Firebase Authentication no React para autenticar usuários usando e-mail e senha. Você armazenará os dados do usuário coletados no Firestore, um banco de dados NoSQL em nuvem também do Firebase.

Observe que este tutorial usa Firebase v9 e React Router v6.

Crie um aplicativo Firebase

Para conectar seu aplicativo ao Firebase, registre-o no Firebase para obter um objeto de configuração. Isto é o que você usará para inicializar o Firebase em seu aplicativo React.

Para criar um aplicativo Firebase, siga as etapas a seguir.

  1. Acesse o console do Firebase e clique em Criar um projeto.
  2. Dê um nome ao seu projeto e clique em criar para iniciar o processo.
  3. Clique no ícone Web () na página de visão geral do seu projeto para registrar o aplicativo.
  4. Dê ao seu aplicativo um nome de sua preferência e clique em Registrar aplicativo. Você não precisa ativar o Firebase Hosting.
  5. Copie o objeto de configuração em Adicionar SDK do Firebase.

Crie um aplicativo React

Use create-react-app para criar um aplicativo React.

npx create-react-app react-auth-firebase

Navegue até a pasta e inicie o aplicativo.

cd react-auth-firebase
npm run start

Autenticar usuários com funções do Firebase

Antes de usar o Firebase, instale-o.

npm i firebase

Crie um novo arquivo, firebase.js e inicialize o Firebase.

import { initializeApp } from "firebase/app";
const firebaseConfig = {
  apiKey: <api_key>,
  authDomain:<auth_domain> ,
  projectId: <project_id>,
  storageBucket: <storage_bucket>,
  messagingSenderId: <messaging_sender_id>,
  appId: <app_id>
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);

Use o objeto de configuração que você copiou ao registrar o aplicativo.

Em seguida, importe os módulos do Firebase que você usará.

import {
  getAuth,
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
} from "firebase/auth";
import { getFirestore, addDoc, collection } from "firebase/firestore";
const db = getFirestore();
const auth = getAuth();

Para autenticar usuários, você precisa criar três funções: signUp, signIn e signOut.

A função signUp passa o e-mail e a senha para createUserWithEmailAndPassword para registrar um novo usuário. createUserWithEmailAndPassword retorna os dados do usuário que você usará para criar um novo registro de usuário no banco de dados.

const signUp = async (email, password) => {
  try {
    const userCredential = await createUserWithEmailAndPassword(
      auth,
      email,
      password
    );
    const user = userCredential.user;
    await addDoc(collection(db, "users"), {
      uid: user.uid,
      email: user.email,
    });
    return true
  } catch (error) {
    return {error: error.message}
  }
};

Observe que você não está verificando se o e-mail já está em uso antes do registro porque o Firebase cuida disso para você.

A seguir, na função signIn passe o e-mail e a senha para a função signInWithEmailAndPassword para fazer login de um usuário cadastrado.

const signIn = async (email, password) => {
  try {
    const userCredential = await signInWithEmailAndPassword(
      auth,
      email,
      password
    );
    const user = userCredential.user;
    return true
  } catch (error) {
    return {error: error.message}
  }
};

As funções signUp e signOut retornam true se forem bem-sucedidas e uma mensagem de erro se ocorrer um erro.

A função signOut é bastante simples. Ele chama a função signOut() do Firebase.

const signOut = async() => {
  try {
    await signOut(auth)
    return true
  } catch (error) {
    return false
  }
};

Crie formulários de reação

Os formulários de login e inscrição coletarão o e-mail e a senha do usuário.

Crie um novo componente Signup.js e adicione o seguinte.

import { useState } from "react";
import { Link } from "react-router-dom";
import { signUp } from "./firebase";
const Signup = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, seterror] = useState("");
  const handleSubmit = async (e) => {
    e.preventDefault();
    if (password !== password2) {
      seterror("Passwords do not match");
    } else {
      setEmail("");
      setPassword("");
      const res = await signUp(email, password);
      if (res.error) seterror(res.error)
    }
  };
  return (
    <>
      <h2>Sign Up</h2>
      <div>
        {error ? <div>{error}</div> : null}
        <form onSubmit={handleSubmit}>
          <input
            type="email"
            name="email"
            value={email}
            placeholder="Your Email"
            required
            onChange={(e) => setEmail(e.target.value)}
          />
          <input
            type="password"
            name="password"
            value={password}
            placeholder="Your Password"
            required
            onChange={(e) => setPassword(e.target.value)}
          />
          <button type="submit">Submit</button>
        </form>
        <p>
          already registered? <Link to="/login">Login</Link>
        </p>
      </div>
    </>
  );
};
export default Signup;

Aqui você está criando um formulário de inscrição e monitorando o e-mail e a senha usando o estado. Depois de enviar o formulário, o evento onSubmit aciona a função handleSubmit() que chama a função signUp() de firebase.js . Se a função retornar um erro, atualize o estado do erro e exiba a mensagem de erro.

Para o formulário de login, crie Signin.js e adicione o seguinte.

import { useState } from "react";
import { signIn } from "./firebase";
const Login = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, seterror] = useState("");
  const handleSubmit = async (e) => {
    e.preventDefault();
    setEmail("");
    setPassword("");
    const res = await signIn(email, password);
    if (res.error) seterror(res.error);
  };
  return (
    <>
      {error ? <div>{error}</div> : null}
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          name="email"
          value={email}
          placeholder="Your Email"
          onChange={(e) => setEmail(e.target.value)}
        />
        <input
          type="password"
          name="password"
          value={password}
          placeholder="Your Password"
          onChange={(e) => setPassword(e.target.value)}
        />
        <input type="submit" value="submit" />
      </form>
    </>
  );
};
export default Login;

O formulário de login é bastante semelhante à página de inscrição, exceto que o envio chama a função signIn().

Por último, crie a página de perfil. Esta é a página para a qual o aplicativo redirecionará os usuários após a autenticação bem-sucedida.

Crie Profile.js e adicione o seguinte.

import { signOut } from "./firebase";
const Profile = () => {
  const handleLogout = async () => {
   await signOut();
  };
  return (
    <>
      <h1>Profile</h1>
 <button onClick={handleLogout}>Logout</button>
    </>
  );
};
export default Profile;

Neste componente, você tem o título Perfil e o botão de logout. O manipulador onClick no botão aciona a função handleLogout que desconecta o usuário.

Crie rotas de autenticação

Para veicular as páginas que você criou no navegador, configure react-router-dom.

Instale react-router-dom:

npm i react-router-dom

Em index.js, configure react-router-dom:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import Login from "./Login";
import Profile from "./Profile";
ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <AuthProvider>
        <Routes>
          <Route path="/" element={<App />} />
          <Route path="login" element={<Login />} />
          <Route path="profile" element={<Profile />} />
        </Routes>
      </AuthProvider>
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

Até este ponto, o aplicativo pode registrar um usuário, inscrevê-lo e desconectá-lo. Então, como você sabe se um usuário está logado ou não?

Na próxima seção deste tutorial, você verá como usar o contexto React para monitorar o status de autenticação de um usuário no aplicativo.

Gerenciar autenticação com React Context API

React Context é uma ferramenta de gerenciamento de estado que simplifica o compartilhamento de dados entre aplicativos. É uma alternativa melhor à perfuração de suporte, onde os dados passam pela árvore de pai para filho até chegarem ao componente que precisa deles.

Criar contexto de autenticação

Na pasta src, adicione o arquivo AuthContext.js e crie e exporte AuthContext.

import { createContext } from "react";
const AuthContext = createContext();
export default AuthContext;

Em seguida, crie o provedor em AuthProvider.js. Isso permitirá que os componentes usem AuthContext.

import { getAuth, onAuthStateChanged } from "firebase/auth";
import { useState, useEffect } from 'react';
import AuthContext from './AuthContext'
const auth = getAuth()
export const AuthProvider = ({ children }) => {
    const [user, setUser] = useState(null);
    useEffect(() => {
        onAuthStateChanged(auth,(user) => {
            setUser(user)
        })
    }, []);
  
    return (
      <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
    );
  };

Aqui, você obtém o valor do usuário usando o método onAuthStateChanged() do Firebase. Este método retorna um objeto de usuário se autenticar o usuário e nulo se não puder. Usando o gancho useEffect(), o valor do usuário é atualizado cada vez que o status de autenticação muda.

Em index.js, envolva as rotas com AuthProvider para garantir que todos os componentes acessem o usuário no contexto:

import { AuthProvider } from "./AuthProvider";
ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <AuthProvider>
        <Routes>
          <Route path="/" element={<App />} />
          <Route path="login" element={<Login />} />
          <Route path="profile" element={<Profile />} />
        </Routes>
      </AuthProvider>
    </BrowserRouter>
    ,
  </React.StrictMode>,
  document.getElementById("root")
);

Crie rotas protegidas

Para proteger rotas confidenciais, verifique o status de autenticação de um usuário que tenta navegar para uma página protegida como a página de perfil.

Modifique Profile.js para redirecionar um usuário se ele não estiver autenticado.

import { useContext } from "react";
import AuthContext from "./AuthContext";
import { useNavigate, Navigate } from "react-router-dom";
import { signOut } from "./firebase";
const Profile = () => {
  const { user } = useContext(AuthContext);
  const navigate = useNavigate();
  const handleLogout = async () => {
   await signOut();
  };
  if (!user) {
    return <Navigate replace to="/login" />;
  }
  return (
    <>
      <h1>Profile</h1>
 <button onClick={handleLogout}>Logout</button>
    </>
  );
};
export default Profile;

O aplicativo renderiza condicionalmente a página de perfil redirecionando o usuário para a página de login se ele não estiver autenticado.

Indo além com a autenticação Firebase

Neste tutorial, você usou o Firebase para autenticar usuários usando email e senha. Você também criou registros de usuário no Firestore. O Firebase fornece funções para trabalhar com provedores de autenticação como Google, Facebook e Twitter.

Artigos relacionados: