React con Firebase

Firebase es una plataforma de desarrollo que incluye múltiples servicios útiles para aplicaciones modernas. En este apartado nos centraremos en la configuración e implementación de la autenticación.
Requisitos previos
- Cuenta de Firebase.
- Proyecto React configurado.
- Documentación de referencia.
Crear un proyecto en Firebase
- Inicia sesión en Firebase Console.
- Haz clic en "Añadir Proyecto".
- Configura el nombre del proyecto y acepta las condiciones de uso.
- Haz clic en "Crear proyecto" y espera a que se configure.
Configurar la aplicación en Firebase
- En el proyecto de Firebase, selecciona "Añadir una aplicación" y elige Web.
- Asigna un nombre a tu aplicación.
- Haz clic en "Registrar aplicación".
- Copia el fragmento de configuración de Firebase que se te proporciona, lo utilizaremos más adelante en el código.
Añadir Firebase al proyecto React
Primero, instala el paquete de Firebase en tu proyecto:
npm install firebase
Configurar Firebase en el proyecto
Crea un archivo src/config/Firebase.jsx
y agrega el código de configuración:
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "TU_API_KEY",
authDomain: "TU_AUTH_DOMAIN",
projectId: "TU_PROJECT_ID",
storageBucket: "TU_STORAGE_BUCKET",
messagingSenderId: "TU_MESSAGING_SENDER_ID",
appId: "TU_APP_ID",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
Próximos pasos
En este punto, ya tienes configurada la base para conectar tu aplicación a Firebase. A continuación:
- Configuraremos el sistema de autenticación en Firebase Console.
- Implementaremos la lógica de inicio de sesión y registro en React.
Crear un usuario de prueba en Firebase
- En Firebase Console, selecciona tu proyecto.
- Ve a la pestaña Authentication desde el menú lateral izquierdo.
- Haz clic en Configurar método de acceso y habilita el método de Correo electrónico y contraseña.
- En la pestaña de usuarios, haz clic en Añadir usuario. Introduce un correo electrónico y contraseña para crear un usuario de prueba.
Implementar Login
En primer lugar vamos a configurar la función de login en nuestro archivo de configuración de firebase.
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "TU_API_KEY",
authDomain: "TU_AUTH_DOMAIN",
projectId: "TU_PROJECT_ID",
storageBucket: "TU_STORAGE_BUCKET",
messagingSenderId: "TU_MESSAGING_SENDER_ID",
appId: "TU_APP_ID",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
// Login function
export const login = ({email, password}) => {
return signInWithEmailAndPassword(auth, email, password)
}
Implementamos el formulario de Login.jsx
para manejar el inicio de sesión:
import { useState } from "react";
import { login } from "../config/firebase";
const Login = () => {
const [email, setEmail] = useState("test@test.com");
const [password, setPassword] = useState("123456");
const handleSubmit = async (e) => {
e.preventDefault();
try {
await login({ email, password });
console.log("user logged in");
} catch (error) {
console.log(error.code);
console.log(error.message);
}
};
return (
<>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
</form>
</>
);
};
export default Login;
Implementar Registro
Configuramos la función de registro en nuestro archivo de configuración de firebase.
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword } from "firebase/auth";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "TU_API_KEY",
authDomain: "TU_AUTH_DOMAIN",
projectId: "TU_PROJECT_ID",
storageBucket: "TU_STORAGE_BUCKET",
messagingSenderId: "TU_MESSAGING_SENDER_ID",
appId: "TU_APP_ID",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
// Login function
export const login = ({email, password}) => {
return signInWithEmailAndPassword(auth, email, password)
}
// Register function
export const register = ({email, password}) => {
return createUserWithEmailAndPassword(auth, email, password)
}
Implementamos el formulario de Registro.jsx
para manejar el registro de nuevos usuarios:
import React, { useState } from 'react'
import { register } from '../config/Firebase'
const Registro = () => {
const [email, setEmail] = useState("test@test.com")
const [password, setPassword] = useState("123456")
const handleSubmit = async (e) => {
e.preventDefault()
try {
await register({email, password})
console.log("User logged in")
} catch (error) {
console.log(error.code)
console.log(error.message)
}
}
return (
<div>
<h1>Registro</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder='email'
value={email}
onChange={(e)=>{setEmail(e.target.value)}}
/>
<input
type="password"
placeholder='password'
value={password}
onChange={(e)=>{setPassword(e.target.value)}}
/>
<button type='submit'>Registrar</button>
</form>
</div>
)
}
export default Registro
Observador para detectar usuarios logueados
Configuramos un observador en el componente UserContext.jsx
, para verificar si hay un usuario autenticado.
import React, { createContext, useEffect, useState } from 'react'
import { auth } from '../config/Firebase'
import { onAuthStateChanged } from 'firebase/auth'
export const UserContext = createContext()
const UserProvider = ({children}) => {
const [user, setUser] = useState(false)
useEffect(()=> {
const unsuscribe = onAuthStateChanged(auth, (user) => {
if (user) {
setUser(user)
} else {
}
return unsuscribe
});
}, [])
if (user===null) return <p>Loading...</p>
return (
<UserContext.Provider value ={{user, setUser}}>
{children}
</UserContext.Provider>
)
}
export default UserProvider
Modificamos el componente Login.jsx
para que, cuando un usuario se loguee, lo redirija al panel privado, Dashboard.jsx
.
import React, { useContext, useEffect, useState } from 'react'
import { login } from '../config/Firebase'
import { useNavigate } from 'react-router-dom'
import { UserContext } from '../context/UserContext'
const Login = () => {
const [email, setEmail] = useState("test@test.com")
const [password, setPassword] = useState("123456")
const {user} = useContext(UserContext)
const navigate = useNavigate()
useEffect(()=> {
if (user) navigate("/dashboard")
}, [user])
const handleSubmit = async (e) => {
e.preventDefault()
try {
await login({email, password})
console.log("User logged in")
} catch (error) {
console.log(error.code)
console.log(error.message)
}
}
return (
<div>
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder='email'
value={email}
onChange={(e)=>{setEmail(e.target.value)}}
/>
<input
type="password"
placeholder='password'
value={password}
onChange={(e)=>{setPassword(e.target.value)}}
/>
<button type='submit'>Login</button>
</form>
</div>
)
}
export default Login
Modificamos el componente Register.jsx
para que, cuando un usuario se registre exitosamente, sea redirigido al panel privado, Dashboard.jsx
.
import React, { useContext, useEffect, useState } from 'react'
import { register } from '../config/Firebase'
import { useNavigate } from 'react-router-dom'
import { UserContext } from '../context/UserContext'
const Registro = () => {
const [email, setEmail] = useState("test@test.com")
const [password, setPassword] = useState("123456")
const {user} = useContext(UserContext)
const navigate = useNavigate()
useEffect(()=> {
if (user) navigate("/dashboard")
}, [user])
const handleSubmit = async (e) => {
e.preventDefault()
try {
await register({email, password})
console.log("User logged in")
} catch (error) {
console.log(error.code)
console.log(error.message)
}
}
return (
<div>
<h1>Registro</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder='email'
value={email}
onChange={(e)=>{setEmail(e.target.value)}}
/>
<input
type="password"
placeholder='password'
value={password}
onChange={(e)=>{setPassword(e.target.value)}}
/>
<button type='submit'>Registrar</button>
</form>
</div>
)
}
export default Registro
Implementar Cerrar Sesión
Añadimos la función para cerrar sesión en el archivo de configuración de firebase, Firebase.jsx
.
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut } from "firebase/auth";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "TU_API_KEY",
authDomain: "TU_AUTH_DOMAIN",
projectId: "TU_PROJECT_ID",
storageBucket: "TU_STORAGE_BUCKET",
messagingSenderId: "TU_MESSAGING_SENDER_ID",
appId: "TU_APP_ID",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
// Login function
export const login = ({email, password}) => {
return signInWithEmailAndPassword(auth, email, password)
}
// Register function
export const register = ({email, password}) => {
return createUserWithEmailAndPassword(auth, email, password)
}
// LogOut function
export const logOut = () => signOut(auth);
Implementamos el botón cerrar sesión en el Nabvar.jsx
:
import { useContext } from "react";
import { NavLink, useNavigate } from "react-router-dom";
import { UserContext } from "../context/UserContext";
import { logOut } from "../config/firebase";
const Navbar = () => {
const {user, setUser} = useContext(UserContext)
const handleLogout = async () => {
await logOut();
setUser(false)
};
return (
<nav>
<NavLink to="/">Home |</NavLink>
<NavLink to="/dashboard"> Dashboard |</NavLink>
<NavLink to="/login"> LogIn |</NavLink>
<NavLink to="/registro"> Register |</NavLink>
<NavLink onClick={handleLogout}> Cerrar sesión</NavLink>
</nav>
);
};
export default Navbar;
Arreglar el Navbar según el estado del usuario
Actualizamos el Navbar.jsx
para mostrar enlaces diferentes dependiendo de si el usuario está autenticado.
import { useContext } from "react";
import { NavLink, useNavigate } from "react-router-dom";
import { UserContext } from "../context/UserContext";
import { logOut } from "../config/firebase";
const Navbar = () => {
const {user, setUser} = useContext(UserContext)
const handleLogout = async () => {
await logOut();
setUser(false)
};
return (
<nav>
<NavLink to="/">Home |</NavLink>
{user && <NavLink to="/dashboard"> Dashboard |</NavLink>}
{
user ? (
<NavLink onClick={handleLogout}> Cerrar sesión |</NavLink>
) : (
<>
<NavLink to="/login"> LogIn |</NavLink>
<NavLink to="/register"> Register</NavLink>
</>
)
}
</nav>
);
};
export default Navbar;
Con esto ya tenemos implementado un sistema de autenticación funcional con Firebase en React.