Una vez creado el proyecto, vamos a la configuración del mismo en la consola de Firebase. Ve a tu proyecto y, en la sección de "Project settings" (configuración del proyecto) en la parte superior izquierda, haz clic en el ícono de engranaje. En la pestaña "General", desplázate hacia abajo y en "Tus aplicaciones", selecciona "Configurar Firebase en la Web".
Cómo integrar Firebase en tu aplicación React para autenticación y base de datos
En este artículo, vamos a explorar cómo integrar Firebase en tu aplicación React para autenticación y base de datos. Lo haremos en dos partes: primero configuraremos Firebase en la consola y luego integraremos el código en Visual Studio Code.
Usaremos como ejemplo un proyecto de una biblioteca virtual para anime y manga, al que llamaremos Animan. Para comenzar, crea una cuenta en Firebase o inicia sesión si ya tienes una. Una vez en la interfaz de Firebase, selecciona "Crear proyecto".
Coloca en nombre de tu preferencia, seleccionas "continuar".
Como es un proyecto de prueba deshabilitamos Google Analytics, pero si deseas activarlo no hay problema.
En unos segundos estará listo.
Luego, se mostrará una ventana con opciones para registrar el proyecto. Aquí se te dará la opción de incluir un dominio o no. En este caso, solo registraremos el proyecto.
Una vez registrado, se te mostrarán los pasos a seguir para la configuración del proyecto y los datos correspondientes. Copia la configuración que aparece, la cual es una clave JSON con tus credenciales de Firebase.
Por otro lado, debemos habilitar los servicios de autenticación y base de datos. Primero, en la sección de Authentication en Firebase Console, hacemos clic en "Empezar" y en la pestaña "Método de inicio de sesión", habilitamos el método de "Correo electrónico/contraseña" para luego hacer clic en "Guardar".
Listo, puedes visualizar que ya está activa la autenticación por correo/contraseña. Si deseas agregar otro método de autenticación, como Google, puedes hacerlo en la opción de agregar otro proveedor.
Para este proyecto, optaremos por usar Firebase Realtime Database debido a su simplicidad y adecuación para proyectos pequeños y sencillos. En cambio, Firestore Database es más adecuado para estructuras de datos más complejas y aplicaciones que requieren consultas avanzadas y mejor escalabilidad. Para obtener más detalles sobre las diferencias entre Firebase Realtime Database y Firestore Database, puedes consultar el siguiente artículo.
Después, en el menú lateral de Firebase Console, vamos a "Realtime Database", creamos la base de datos en el modo de prueba (suficiente para desarrollo), hacemos clic en "Siguiente" y finalmente en habilitar.
Por defecto, se escoge la ubicación más cercana. Sin embargo, si el usuario lo requiere, se puede cambiar esta opción.
Con las configuraciones en la consola de Firebase completas, es momento de pasar al código. Primero, instalamos Firebase utilizando npm:
npm install firebase
Después, creamos un archivo llamado firebaseConfig.ts
en la carpeta src
de nuestro proyecto. En este archivo, pegamos la configuración proporcionada anteriormente por Firebase.
Importante: Ingresas a la consola de Firebase, y en Realtime Database vas a visualizar la URL, esta se debe agregar a la configuración en el archivo firebaseConfig.ts
databaseURL: "https://animan-ecfce-default-rtdb.firebaseio.com",
Debería verse algo así:
Una vez configurado Firebase y Realtime Database, vamos al código.
Configuración de Firebase en el Código
Después de haber configurado Firebase en la consola y habilitado los servicios necesarios, es momento de integrarlo en nuestro código.
1. Instalación de Firebase
Para poder utilizar Firebase en nuestro proyecto React, necesitamos instalar el paquete oficial de Firebase utilizando npm. En la terminal, dentro de la carpeta de nuestro proyecto, ejecutamos:
Este comando descargará e instalará Firebase en nuestro proyecto, permitiéndonos utilizar sus servicios.
2. Creación del Archivo de Configuración
Una vez instalado Firebase, debemos crear un archivo donde almacenaremos la configuración de nuestra aplicación. En la carpeta src
, creamos un archivo llamado firebaseConfig.ts
y pegamos la configuración proporcionada por Firebase.
El contenido de este archivo debe seguir la siguiente estructura:
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getDatabase } from "firebase/database";
const firebaseConfig = {
apiKey: "TU_API_KEY",
authDomain: "TU_AUTH_DOMAIN",
databaseURL: "URL"
projectId: "TU_PROJECT_ID",
storageBucket: "TU_STORAGE_BUCKET",
messagingSenderId: "TU_MESSAGING_SENDER_ID",
appId: "TU_APP_ID",
databaseURL: "TU_DATABASE_URL",
};
// Inicializamos Firebase
const app = initializeApp(firebaseConfig);
// Exportamos los servicios necesarios
export const auth = getAuth(app); // Para la autenticación
export const db = getDatabase(app); // Para Realtime Database
Nota : Recuerda reemplazar los valores de
firebaseConfig
con los datos reales de tu proyecto en Firebase.
Este archivo inicializa Firebase en nuestra aplicación y exporta los módulos de autenticación ( auth
) y base de datos ( database
) para que podamos usarlos en otros archivos.
3. Implementación de la Autenticación
Para manejar la autenticación de manera eficiente, crearemos un contexto que almacenará la información del usuario y proporcionará funciones para iniciar y cerrar sesión.
En la carpeta contexts
, creamos un archivo llamado AuthContext.tsx
con el siguiente código:
import React, { createContext, useContext, useEffect, useState } from "react";
import { User, onAuthStateChanged, signOut } from "firebase/auth";
import { auth } from "../firebaseConfig";
interface AuthContextProps {
user: User | null;
loading: boolean;
logout: () => Promise;
}
const AuthContext = createContext(undefined);
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
setLoading(false);
});
return () => unsubscribe();
}, []);
// Implementación de logout
const logout = async () => {
try {
await signOut(auth); // Cierra la sesión en Firebase
setUser(null); // Limpia el estado del usuario
} catch (error) {
console.error("Error al cerrar sesión:", error);
}
};
return (
{children}
);
};
export const useAuth = (): AuthContextProps => {
const context = useContext(AuthContext);
if (!context) {
throw new Error("useAuth debe usarse dentro de un AuthProvider");
}
return context;
};
Para gestionar la autenticación de usuarios en el proyecto, se implementó un contexto de autenticación usando React y Firebase. Esto centraliza la gestión del usuario y facilita el acceso a su información en toda la aplicación sin necesidad de prop-drilling.
Importaciones: Se importaron createContext
, useContext
, useEffect
, y useState
desde React, y onAuthStateChanged
, signOut
, y auth
desde Firebase.
Interfaz AuthContextProps
: Define tres propiedades clave:
user
: Almacena el usuario autenticado onull
si no hay sesión.loading
: Indica si la aplicación está verificando la autenticación.logout
: Función asíncrona para cerrar sesión.
Creación del contexto: Se creó el contexto con createContext<AuthContextProps | undefined>(undefined)
, lo que obliga a verificar su existencia antes de usarlo.
Componente AuthProvider
: Encargado de proveer el contexto de autenticación. Dentro de él:
- Se definieron dos estados:
user
(usuario autenticado) yloading
(verificación de sesión). - Se usó
useEffect
cononAuthStateChanged
para escuchar cambios en la sesión del usuario, actualizandouser
y cambiandoloading
afalse
una vez verificada la sesión. - Se implementó una función de limpieza
unsubscribe()
para evitar fugas de memoria. - Función
logout
: Cierra la sesión del usuario llamando asignOut(auth)
y actualizauser
anull
. Captura y muestra errores en la consola si ocurren. - Provisión del contexto: Los valores
user
,loading
, ylogout
se pasaron alAuthContext.Provider
, permitiendo que cualquier componente dentro deAuthProvider
acceda a ellos. - Hook
useAuth
: Facilita el acceso al contexto en otros componentes. Verifica si el contexto existe y lanza un error si se usa fuera deAuthProvider
.
4. Creación del Servicio de Base de Datos
Para almacenar y gestionar los datos de nuestra biblioteca virtual de anime, utilizaremos Firebase Realtime Database. En la carpeta services
, creamos un archivo llamado realtimeDatabaseService.ts
, el cual contendrá las funciones para interactuar con la base de datos.
import { db } from "../firebaseConfig";
import { ref, push, get, onValue, off, child } from "firebase/database";
import { auth } from "../firebaseConfig";
// Función para agregar un nuevo anime
export const addAnime = async (title: string, status: string) => {
try {
const animesRef = ref(db, "animes");
await push(animesRef, {
Title: title,
Status: status
});
console.log("Anime agregado correctamente");
} catch (error) {
console.error("Error al agregar anime:", error);
}
};
// Función para obtener todos los animes
export const getAnimes = async () => {
try {
// Verificar si el usuario está autenticado
if (!auth.currentUser) {
console.log("Usuario no autenticado");
return null;
}
const snapshot = await get(child(ref(db), "animes"));
if (snapshot.exists()) {
return snapshot.val();
} else {
console.log("No hay datos disponibles.");
return null;
}
} catch (error) {
console.error("Error al obtener los animes:", error);
return null;
}
};
// Función para escuchar cambios en la colección "animes"
export const listenToAnimes = (callback: (animes: Record | null) => void) => {
const animesRef = ref(db, "animes");
const unsubscribe = onValue(animesRef, (snapshot) => {
if (snapshot.exists()) {
callback(snapshot.val());
} else {
callback(null);
}
});
// Devuelve una función para cancelar la suscripción
return () => off(animesRef, "value", unsubscribe);
};
Se implementaron funciones para interactuar con Firebase Realtime Database, permitiendo agregar, obtener y escuchar cambios en la lista de animes en tiempo real.
Importaciones: Se utilizaron métodos de Firebase como ref
, push
, get
, onValue
, off
, y child
, junto con auth
para validar la autenticación del usuario.
Agregar un anime (addAnime
):
- Recibe el título y estado del anime.
- Usa
push
en la referenciaref(db, "animes")
para añadir un nuevo anime. - Muestra un mensaje de éxito o error en la consola.
Obtener la lista de animes (getAnimes
):
- Verifica si el usuario está autenticado con
auth.currentUser
. - Usa
get
conchild(ref(db), "animes")
para recuperar los animes. - Devuelve los datos o
null
si no hay información disponible.
Escuchar cambios en tiempo real (listenToAnimes
):
- Recibe un callback para pasar los datos actualizados.
- Usa
onValue
enref(db, "animes")
para escuchar cambios. - Retorna una función para cancelar la suscripción con
off
, optimizando el uso de recursos.
5. Creación de Pages y Componentes
En este caso creamos tres pages y dos componentes con relación a nuestra temática, pero dependerá de los alcances y preferencias de tu proyecto.
En la carpeta Pages, creamos tres archivos, Register.tsx, Login.tsx, Dashboard.tsx.
- El componente Register.tsx es una página que proporciona la interfaz y la lógica para el registro de usuarios en la aplicación. Para gestionar el estado, se utilizan dos variables:
email
ypassword
, que almacenan los valores ingresados en los campos del formulario. También se usauseNavigate
para redirigir al usuario a la página de dashboard una vez que el registro se complete con éxito. - Al enviar el formulario, la función
handleRegister
evita el comportamiento por defecto del navegador y llama acreateUserWithEmailAndPassword
de Firebase Authentication, utilizando los datos ingresados. Si el registro es exitoso, el usuario es redirigido al dashboard. En caso de error, se maneja la excepción y se muestra un mensaje en la consola.
- El componente Login.tsx es una página diseñada para que los usuarios puedan iniciar sesión en la aplicación. En primer lugar, se utilizan los estados
email
ypassword
para almacenar los datos ingresados por el usuario en los campos del formulario. También se empleauseNavigate
para redirigir al usuario al dashboard una vez que haya iniciado sesión con éxito. - La función
handleLogin
se ejecuta cuando el usuario envía el formulario. Esta función evita el comportamiento predeterminado del navegador y llama asignInWithEmailAndPassword
de Firebase Authentication, utilizando las credenciales proporcionadas. Si la autenticación es exitosa, el usuario es redirigido al dashboard. En caso de error, se captura la excepción y se muestra un mensaje en la consola.
El componente Dashboard.tsx es la página principal de la aplicación, donde los usuarios pueden gestionar su lista de animes y mangas.
- En primer lugar, se utiliza el hook
useAuth
para obtener la funciónlogout
, que permite cerrar sesión, yuseNavigate
para redirigir al usuario a la página de inicio de sesión tras desloguearse. - La función
handleLogout
se encarga de ejecutarlogout()
y, en caso de éxito, lleva al usuario de vuelta a/login
. Si ocurre un error, este se muestra en la consola.
A su vez, se han creado dos componentes principales para gestionar la lista de animes: AddAnime y AnimeList.
- El componente AddAnime permite a los usuarios agregar nuevos animes a la base de datos. Para ello, define dos estados:
title
, que almacena el nombre del anime, ystatus
, que indica su estado (Visto
,En progreso
oPendiente
). Al enviar el formulario, la funciónhandleAddAnime
llama aaddAnime
para guardar los datos en Firebase. Luego, los campos se restablecen para permitir nuevas entradas. La interfaz incluye un campo de texto para el nombre y unselect
para elegir el estado, junto con un botón de envío.
- Por otro lado, el componente AnimeList muestra la lista de animes registrados en la base de datos en tiempo real. Usa el contexto de autenticación para asegurarse de que solo los usuarios autenticados puedan ver los datos. Al montarse, la función
listenToAnimes
establece una suscripción que escucha cambios en la base de datos y actualiza el estadoanimes
con la información recibida. Cada anime se representa en unli
, mostrando su título y estado. Si no hay animes registrados, se muestra un mensaje indicándolo.
6. Rutas
Para gestionar la navegación en nuestra aplicación, instalamos la biblioteca React Router, lo que nos permite definir rutas y controlar el acceso a diferentes páginas.
En el archivo App.tsx, importamos BrowserRouter
(alias Router
), Routes
y Route
de react-router-dom
para estructurar la navegación. También incluimos Navigate
para redirigir a los usuarios en función de su estado de autenticación.
Dentro del componente App
, obtenemos el usuario autenticado y su estado de carga a través del hook useAuth
. Si la aplicación aún está cargando, mostramos un mensaje de "Cargando...".
Luego, definimos las rutas de la aplicación:
- Si el usuario no ha iniciado sesión, puede acceder a
/login
y/register
. De lo contrario, será redirigido a/dashboard
. - Si el usuario está autenticado, se le permite entrar a
/dashboard
, pero si no lo está, será redirigido a/login
. - Cualquier ruta desconocida llevará automáticamente a
/login
.
Tambien se uso Tailwind Css, pero todo depene de la libreria y estilo que prefieras, aca podras encontrar el repositorio si deseas practicar.
Integrar Firebase en una aplicación React es un proceso que requiere configurar la consola de Firebase, habilitar la autenticación y la base de datos, y luego conectar estos servicios al código del proyecto. En este artículo, hemos visto cómo hacerlo paso a paso, desde la instalación de Firebase hasta la implementación de un sistema de autenticación y almacenamiento de datos en tiempo real con Realtime Database.
Al estructurar la aplicación con contextos para la autenticación y servicios específicos para la base de datos, logramos una separación clara de responsabilidades, lo que facilita la escalabilidad y el mantenimiento del código. Además, el uso de React Router permite gestionar la navegación de manera eficiente, asegurando que solo los usuarios autenticados puedan acceder a ciertas secciones de la aplicación.