Introducción
Cuando desarrollamos una aplicación web, normalmente nos concentramos en que tenga una buena interfaz y que sus funciones trabajen correctamente. Sin embargo, una aplicación completa también necesita almacenar información, proteger los datos de sus usuarios y estar disponible desde Internet.
En este proyecto decidí desarrollar TaskFlow, una aplicación web para gestionar tareas personales utilizando React y Firebase Cloud Firestore como base de datos NoSQL. La idea fue construir un sistema sencillo, pero que permitiera trabajar con datos reales, implementar autenticación y automatizar su publicación en la nube.
Además, quería comprobar cómo funcionaba un proyecto que no dependiera de una base de datos relacional tradicional como MySQL o SQL Server. Por eso elegí Firestore, que permite almacenar información mediante colecciones y documentos.
El desarrollo también me permitió trabajar con GitHub, Firebase Hosting y GitHub Actions, herramientas que se complementan para llevar una aplicación desde mi computadora hasta un entorno público.
- ¿Qué es TaskFlow y qué problema resuelve?
TaskFlow es una aplicación web que permite registrar, organizar y realizar seguimiento de tareas personales.
La necesidad que busca resolver es bastante común: cuando tenemos varias actividades pendientes, podemos perder el control de cuáles ya terminamos, cuáles estamos desarrollando y cuáles todavía no hemos comenzado.
Para solucionar esto, implementé las siguientes funcionalidades:
- Registro e inicio de sesión mediante correo electrónico y contraseña.
- Creación de tareas con título, descripción y fecha límite.
- Visualización de todas las tareas registradas.
- Modificación de la información de una tarea.
- Clasificación mediante los estados pendiente, en proceso y completada.
- Eliminación de tareas que ya no necesitamos.
- Filtrado de las tareas según su estado.
- Almacenamiento de la información en Firebase Firestore.
- Separación de las tareas según el usuario autenticado.
Aunque se trata de una aplicación relativamente pequeña, reúne funcionalidades que también podemos encontrar en sistemas de gestión más grandes.
- Tecnologías utilizadas
Para desarrollar el proyecto utilicé distintas herramientas, cada una con una función específica.
| Tecnología | Función |
|---|---|
| React | Construcción de los componentes de la interfaz |
| Vite | Entorno de desarrollo y compilación |
| JavaScript | Lógica y funcionalidades del sistema |
| CSS | Diseño visual y adaptación a diferentes pantallas |
| Firebase Authentication | Registro e inicio de sesión de usuarios |
| Cloud Firestore | Almacenamiento de los documentos NoSQL |
| Git y GitHub | Control de versiones y repositorio público |
| GitHub Actions | Automatización de la compilación y despliegue |
| Firebase Hosting | Publicación de la aplicación en Internet |
Elegí React porque permite construir interfaces mediante componentes y actualizar los elementos visuales cuando cambian los datos.
Por otro lado, Firebase me permitió trabajar con una base de datos alojada en la nube, sin tener que instalar y administrar un servidor de base de datos propio.
3. ¿Por qué utilicé una base de datos NoSQL?
Una de las decisiones principales del proyecto fue utilizar Cloud Firestore.
A diferencia de una base de datos relacional, donde normalmente organizamos la información en tablas, filas y columnas, Firestore utiliza colecciones y documentos.
Por ejemplo, en TaskFlow creé una colección llamada tareas. Dentro de ella, cada tarea se almacena como un documento con su propio identificador.
Un documento tiene una estructura similar a la siguiente:
{ "titulo": "Primera tarea NoSQL", "descripcion": "Comprobar la conexión con Firebase", "estado": "Pendiente", "fecha": "2026-11-20", "creada": "2026-11-14T23:08:15.890Z", "usuarioId": "identificador_del_usuario" } En este caso, el documento almacena la información de una tarea sin que tengamos que definir previamente una tabla SQL.
Algo importante es que Firestore también permite trabajar con consultas, reglas de seguridad y actualizaciones en tiempo real.
Esto fue especialmente útil en TaskFlow, porque las tareas pueden mostrarse nuevamente en la interfaz cuando se produce un cambio en la base de datos.
Organización de los datos
La estructura utilizada fue:
Cloud Firestore └── tareas ├── Documento 1 │ ├── titulo │ ├── descripcion │ ├── estado │ ├── fecha │ ├── creada │ └── usuarioId │ └── Documento 2 ├── titulo ├── descripcion ├── estado ├── fecha ├── creada └── usuarioId Cada documento tiene un identificador generado por Firestore. El campo usuarioId permite relacionar las tareas con la cuenta que las creó.
- Creación del proyecto con React y Vite
Comencé el desarrollo desde Visual Studio Code, utilizando Node.js y npm para gestionar las dependencias.
Primero ejecuté:
npm create vite@latest taskflow -- --template react Después ingresé a la carpeta e instalé las dependencias:
cd taskflow npm install Para iniciar el servidor de desarrollo utilicé:
npm run dev Con esto pude abrir la aplicación desde el navegador mediante una dirección local como:
http://localhost:5173/
Al principio aparecía la pantalla predeterminada de Vite. Posteriormente la reemplacé por la interfaz de TaskFlow.
Diseño de la interfaz
Busqué que la aplicación tuviera una apariencia sencilla y organizada. Para ello desarrollé un panel con menú lateral, tarjetas de estadísticas, formulario de registro y listado de tareas.
También incorporé colores diferentes para representar los estados:
- Pendiente: color naranja.
- En proceso: color azul.
- Completada: color verde.
La intención fue que el usuario pudiera identificar rápidamente el avance de sus actividades sin tener que ingresar a cada una.
- Conexión de React con Firebase
Una vez terminada la interfaz, el siguiente paso fue conectar la aplicación con los servicios de Firebase.
Primero creé el proyecto taskflow-nosql desde Firebase Console y registré una aplicación web.
Después instalé el SDK de Firebase:
npm install firebase Dentro de la carpeta src creé un archivo llamado firebase.js, encargado de inicializar Firebase y exportar los servicios utilizados.
La estructura principal es la siguiente:
import { initializeApp } from 'firebase/app'; import { getFirestore } from 'firebase/firestore'; import { getAuth } from 'firebase/auth'; const firebaseConfig = { // Configuración de la aplicación web // proporcionada por Firebase Console }; const app = initializeApp(firebaseConfig); export const db = getFirestore(app); export const auth = getAuth(app); Con esta configuración preparé dos servicios: db, para acceder a Cloud Firestore, y auth, para trabajar con Firebase Authentication.
Un detalle importante es que la configuración del cliente no debe confundirse con las claves privadas de una cuenta de servicio. Estas últimas nunca deben publicarse en un repositorio.
6. Implementación del registro e inicio de sesión
Antes de conectar todas las tareas a Firestore, consideré necesario implementar autenticación.
Para ello habilité el método de correo electrónico y contraseña en Firebase Authentication.
Después desarrollé un componente llamado AuthGate.jsx, encargado de comprobar si existe una sesión activa.
Para registrar usuarios utilicé:
import { createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut } from 'firebase/auth'; Por ejemplo, para registrar una cuenta se utiliza:
await createUserWithEmailAndPassword( auth, correo, password ); Y para iniciar sesión:
await signInWithEmailAndPassword( auth, correo, password ); De esta manera, el usuario primero debe autenticarse para acceder al panel de tareas.
Durante esta implementación encontré un error relacionado con una API Key que Firebase no reconocía. Después de revisar el mensaje de error, recuperé la configuración original desde Firebase Console y corregí el archivo de conexión.
Esta experiencia me permitió entender que, cuando un servicio externo falla, resulta importante revisar el código específico del error en lugar de modificar varias partes de la aplicación sin saber cuál es el problema.
- Implementación de las operaciones CRUD en Firestore
Una vez configurada la autenticación, conecté las principales funcionalidades de TaskFlow con Cloud Firestore.
Las operaciones CRUD permiten crear, consultar, actualizar y eliminar información.
Crear una tarea (CREATE)
Para registrar una tarea utilicé la función addDoc():
await addDoc(collection(db, 'tareas'), { titulo: formulario.titulo, descripcion: formulario.descripcion, fecha: formulario.fecha, estado: formulario.estado, usuarioId: usuario.uid, creada: new Date().toISOString() }); Cuando el usuario presiona el botón de crear tarea, los datos se envían a Firestore y se genera automáticamente un documento.
Consultar las tareas (READ)
Para recuperar las tareas implementé una consulta filtrada mediante el identificador del usuario.
const consulta = query( collection(db, 'tareas'), where('usuarioId', '==', usuario.uid) ); Además, utilicé onSnapshot() para escuchar los cambios en tiempo real.
onSnapshot(consulta, (snapshot) => { const tareas = snapshot.docs.map((documento) => ({ ...documento.data(), id: documento.id })); setTareas(tareas); }); Esto permite que el listado se actualice cuando Firestore informa de cambios, sin tener que recargar manualmente toda la aplicación.
Actualizar una tarea (UPDATE)
Para editar las tareas utilicé updateDoc():
await updateDoc( doc(db, 'tareas', idTarea), { titulo: nuevoTitulo, descripcion: nuevaDescripcion, estado: nuevoEstado } ); Con esta operación podemos modificar el contenido de un documento existente, manteniendo su identificador.
También utilicé esta función para cambiar el estado de una tarea a completada.
Eliminar una tarea (DELETE)
Finalmente, implementé la eliminación mediante deleteDoc():
await deleteDoc( doc(db, 'tareas', idTarea) ); Antes de eliminar, la aplicación solicita una confirmación al usuario.
De esta manera, TaskFlow cuenta con las cuatro operaciones CRUD conectadas directamente con una base de datos NoSQL.
- Seguridad de la información
Además de registrar usuarios, fue necesario proteger las tareas almacenadas en Firestore.
Para ello configuré reglas de seguridad basadas en Firebase Authentication.
La lógica principal consiste en comprobar que el usuario esté autenticado y que el campo usuarioId del documento coincida con su identificador.
Una regla utilizada para consultar tareas fue:
allow read: if request.auth != null && resource.data.usuarioId == request.auth.uid; También configuré restricciones para crear, actualizar y eliminar documentos.
En la actualización se comprueba tanto la propiedad actual como que el documento mantenga el mismo propietario.
Estas reglas permiten establecer un primer nivel de separación entre usuarios. Para una versión de producción más exigente también sería recomendable validar los campos, tipos de datos y tamaños de los documentos.
9. Publicación del código en GitHub
Después de desarrollar y probar la aplicación, utilicé Git para controlar las versiones y publicar el código fuente.
Inicialicé el repositorio local:
git init Después preparé los archivos y registré los cambios:
git add . git commit -m "Version inicial de TaskFlow con React y Firebase" Finalmente conecté el repositorio local con GitHub y publiqué los archivos en la rama principal.
git branch -M main git push -u origin main También configuré .gitignore para evitar incluir carpetas innecesarias como node_modules y archivos privados de entorno.
El repositorio público contiene el código de la aplicación y permite revisar cómo se implementaron las funcionalidades.
Repositorio del proyecto:
https://github.com/fm2021072628/taskflow-nosql-firebase
- Despliegue de la aplicación en Firebase Hosting
Una vez publicado el repositorio, el siguiente objetivo fue hacer que TaskFlow estuviera disponible desde Internet.
Para ello utilicé Firebase Hosting, un servicio que permite alojar aplicaciones web.
Primero instalé Firebase CLI:
npm install -g firebase-tools Después inicié sesión:
firebase login Configuré Hosting para utilizar la carpeta dist, porque allí Vite genera los archivos de producción.
Para compilar la aplicación ejecuté:
npm run build Y posteriormente:
firebase deploy --only hosting Firebase confirmó que los archivos se habían cargado y que la nueva versión estaba publicada.
Finalmente obtuve la dirección pública:
Aplicación desplegada:
https://taskflow-nosql.web.app
Gracias a esto, TaskFlow dejó de depender de mi computadora y pasó a estar disponible mediante una dirección web pública.
- Automatización del despliegue con GitHub Actions
Una de las partes más interesantes del proyecto fue automatizar la publicación.
Inicialmente, cada vez que necesitaba actualizar la aplicación, debía ejecutar manualmente los comandos de compilación y despliegue.
Aunque este procedimiento funciona, no resulta tan práctico cuando realizamos cambios constantemente.
Por eso decidí integrar GitHub Actions con Firebase Hosting.
¿Cómo funciona la automatización?
El proceso es el siguiente:
- Modifico el código de TaskFlow en Visual Studio Code.
- Registro los cambios mediante Git.
- Envío los cambios a la rama
mainde GitHub. - GitHub Actions detecta la actualización.
- Se ejecuta el flujo configurado para compilar y publicar la aplicación.
- Firebase Hosting recibe la nueva versión.
Para preparar la automatización utilicé:
firebase init hosting:github Este comando generó archivos de configuración dentro de:
.github/ └── workflows/ ├── firebase-hosting-merge.yml └── firebase-hosting-pull-request.yml El primero permite desplegar cuando se incorporan cambios a la rama principal. El segundo permite trabajar con versiones de vista previa para solicitudes de extracción.
Problema durante la configuración
No todo funcionó en el primer intento.
Durante la integración, Firebase mostró un error relacionado con una cuenta de servicio de Google Cloud que no podía encontrar.
Para resolverlo revisé la sección de IAM, confirmé la existencia de la cuenta de servicio creada para GitHub Actions y configuré los permisos necesarios para Firebase Hosting.
Después repetí la configuración y Firebase consiguió generar los archivos del flujo de trabajo.
Finalmente envié esos archivos al repositorio mediante Git.
Resultado de la automatización
Al ingresar a la pestaña Actions del repositorio, pude observar una ejecución de GitHub Actions asociada al despliegue de Firebase Hosting.
La ejecución finalizó correctamente y apareció una marca verde, con una duración registrada de aproximadamente 50 segundos.
Esto confirmó que el flujo de automatización se había ejecutado sin errores.
Automatización del proyecto:
https://github.com/fm2021072628/taskflow-nosql-firebase/actions
12. Pruebas realizadas
Durante el desarrollo realicé distintas pruebas para comprobar las funcionalidades principales.
| Prueba | Resultado observado |
|---|---|
| Registro de tareas | Se creó un documento en Cloud Firestore |
| Consulta de tareas | Las tareas aparecieron en la interfaz |
| Edición | Se modificó el título, la descripción y el estado de una tarea |
| Cambio de estado | Se visualizaron los estados pendiente, en proceso y completada |
| Autenticación | Se implementó el registro y acceso con Firebase |
| Compilación | Vite generó correctamente la aplicación de producción |
| Despliegue | Firebase Hosting confirmó la publicación |
| Automatización | GitHub Actions mostró una ejecución exitosa |
Estas pruebas permitieron comprobar la integración entre React, Firebase y GitHub.
Sin embargo, todavía quedan mejoras que podrían incorporarse, como ampliar las pruebas de seguridad entre diferentes cuentas y optimizar el tamaño del JavaScript generado.
13. Dificultades encontradas y soluciones
Durante el desarrollo aparecieron algunos problemas que considero importantes mencionar porque forman parte del aprendizaje.
Error en la configuración de Firebase. Al principio, Firebase Authentication rechazaba la API Key. Lo solucioné recuperando la configuración correcta desde Firebase Console.
Diferencia entre almacenamiento local y NoSQL. Inicialmente las tareas se guardaban en el navegador mediante localStorage. Después sustituí ese almacenamiento por operaciones con Firestore, permitiendo trabajar con documentos almacenados en la nube.
Errores al configurar GitHub Actions. La integración automática presentó problemas de autorización y de cuentas de servicio. Para solucionarlos tuve que revisar la configuración de Google Cloud IAM.
Advertencia durante la compilación. Vite informó que uno de los archivos JavaScript generados era relativamente grande. La compilación terminó correctamente, pero esta advertencia señala una oportunidad de optimización futura.
Estas dificultades me ayudaron a comprender mejor la relación entre el código de una aplicación y los servicios que necesita para funcionar.
14. Posibles mejoras del proyecto
Aunque TaskFlow ya cuenta con las funcionalidades principales, todavía se podrían incorporar mejoras.
Por ejemplo, sería útil agregar prioridades a las tareas, implementar búsqueda por palabras clave y mostrar estadísticas más detalladas sobre las actividades completadas.
También podría mejorarse la interfaz de autenticación, incorporando recuperación de contraseña y verificación de correo electrónico.
Desde el lado técnico, sería recomendable ampliar las validaciones de Firestore, realizar pruebas automatizadas y optimizar el tamaño de los archivos de producción.
Estas mejoras permitirían convertir TaskFlow en una herramienta más completa y preparada para un mayor número de usuarios.
15. Conclusiones
Desarrollar TaskFlow me permitió comprender que crear una aplicación web no consiste únicamente en diseñar pantallas o programar botones. También es necesario pensar en dónde se almacenarán los datos, cómo se protegerán y de qué manera se publicará el sistema.
Uno de los aprendizajes principales fue trabajar con una base de datos NoSQL como Cloud Firestore. A través de sus colecciones y documentos pude implementar operaciones CRUD sin tener que construir una base de datos relacional tradicional.
Otro aspecto importante fue la integración de Firebase Authentication, porque permitió incorporar el concepto de usuarios autenticados y separar sus tareas mediante identificadores.
Finalmente, GitHub Actions me ayudó a comprender cómo funciona la automatización dentro del desarrollo de software. En lugar de depender completamente de comandos manuales, es posible preparar un flujo que ejecute tareas de compilación y despliegue cuando se actualiza el repositorio.
En general, este proyecto me permitió aplicar diferentes conocimientos en una sola aplicación: desarrollo frontend, bases de datos NoSQL, autenticación, control de versiones, servicios en la nube y automatización.
Lo que más destaco es que pude pasar de una aplicación que inicialmente funcionaba solo en mi computadora a un sistema publicado en Internet, con almacenamiento en la nube y un flujo de despliegue automatizado.
Enlaces del proyecto
Repositorio público de GitHub:
https://github.com/fm2021072628/taskflow-nosql-firebase
Aplicación web publicada:
https://taskflow-nosql.web.app
GitHub Actions — Automatización:
https://github.com/fm2021072628/taskflow-nosql-firebase/actions
Video demostrativo:
[PENDIENTE: agregar enlace del video publicado en YouTube]
Referencias y documentación
- React. Documentación oficial: https://react.dev/
- Vite. Documentación oficial: https://vite.dev/
- Firebase. Cloud Firestore: https://firebase.google.com/docs/firestore
- Firebase. Authentication: https://firebase.google.com/docs/auth
- Firebase. Hosting: https://firebase.google.com/docs/hosting
- GitHub. GitHub Actions: https://docs.github.com/en/actions





