Firebase

Aplicación para deudas y gastos compartidos – Gratuita y open source

Hoy voy a enseñarte una app móvil y web que sirve para llevar el registro de las deudas y gastos compartidos entre cierto grupo de personas.

En esta app puedes registrar las deudas que tienes, y las otras personas pueden registrar lo que tú le debes a ellas. Además, las deudas o gastos pueden ser de persona a persona o compartidas entre todos.

A lo largo de este post te mostraré las características de la app, los módulos que tiene y cómo funciona. Desde ahora te cuento que esta es una PWA y puede ser usada en móviles o en computadoras como si fuera nativa.

Entre sus características encontramos:

  1. Sincronización de datos en tiempo real
  2. Trabajo sin conexión (los datos se suben cuando la conexión regresa)
  3. PWA que puede ser usada como nativa o en el navegador web
  4. Manejo de usuarios
  5. Control de deudas con opción para repartir los gastos y liquidar las deudas
  6. Filtros para acreedores y deudores
  7. Totalmente gratuita y open source, puede ser usada como un proyecto de estudiante
  8. Tú puedes tener tu propia versión, solo debes configurar el SDK de Firebase y comenzar a usar la app

Por cierto, la he hecho usando Firebase con Firestore Database y Vue con Buefy.

Demostración

Puedes probar la app terminada aquí: https://parzibyte.github.io/deudas_compartidas/#/login

Inicia sesión con el usuario Luis y la contraseña 123. Te aviso que no se pueden editar ni eliminar usuarios ya que he deshabilitado esas operaciones en la colección, pero si tú clonas el repositorio y configuras tu base de datos podrás habilitarlo.

Puedes instalar la app como nativa:

Instalar aplicación de deudas compartidas como nativa gracias a las PWA

O usarla directamente en el navegador, ya que todo se va a guardar en caché tan pronto visites la página por primera vez. Solo porque me gusta cómo se ve, así luce la splash screen:

Splash screen de Aplicación de control de deudas y gastos instalada como nativa en Android

Ejemplo de uso

Esta app se parece a la que hice sobre el control de pagos, pero es distinta. Esto es para llevar deudas compartidas entre varios usuarios que tengan la app, para que haya transparencia.

Por ejemplo, supongamos que tú vives con 2 compañeros de escuela y todos usan las cosas por igual; los gastos se pueden dividir.

Si tú compras una lata de café en 300 pesos entonces registras esa compra en la app y así tus compañeros van a reponer su parte de 100 pesos, ya que son 3 personas: tú y ellos 2. Tal vez después uno de ellos compre otra cosa, para lo cual va a registrarlo en la app y ahora tú le deberás tu parte.

Al final del período (mes, semana, día) se reúnen y hacen algo como un corte de caja para saber cuánto se le debe a cada uno. Se hacen los pagos correspondientes y se liquidan las deudas.

Obviamente ese ejemplo es muy simple, pero me imagino que puede ser usada para muchísimas cosas más.

Gestión de usuarios

La app cuenta con login y registro de usuarios. Obviamente debes haber iniciado sesión para crear otros usuarios.

Al registrarse se solicita el nombre y la contraseña. Esta contraseña es almacenada de manera segura y cifrada con bcrypt.

Gestión de usuarios en PWA para deudas y gastos

Una vez que han sido registrados ya pueden iniciar sesión y todo eso. Pueden cerrar sesión desde el menú:

Menú de app de gastos compartidos

Agregar deuda

Llegamos al punto principal de la aplicación: el de guardar las deudas compartidas que tenemos, o las deudas que existen entre usuarios o compañeros.

El acreedor de la deuda solo puede ser el usuario autenticado. Los demás usuarios quedan deshabilitados:

Registrar nueva deuda con acreedor y deudor en aplicación web

Reporte de deudas

Ya en el caso de las deudas tenemos filtros para mostrar solo las de determinado acreedor, deudor o por estado de la deuda (Liquidada, pendiente o ambas):

Reporte de deudas – Filtro por acreedor, deudor o estado de liquidación

También se nos muestran los totales que cada persona debe. Y ya con los filtros podemos hacer más preciso ese reporte.

Permisos de la deuda

Ahora que un usuario ha registrado un nuevo gasto compartido, los otros usuarios pueden verlo y filtrarlo, pero no modificarlo.

Cada usuario solo puede modificar sus propias deudas, o mejor dicho, marcar como pagadas sus propias deudas. Por ejemplo, Chris no puede modificar algo de Luis:

Permisos de deuda

Y del mismo modo, Luis no puede modificar algo de Chris. Así pasa con todos los usuarios.

Marcando deuda como pagada y liquidada

Ahora veamos lo que puede hacer un usuario con las deudas que él ha registrado. Tomé como paradigma una libreta, pues normalmente los usuarios registran las deudas ahí.

En una libreta uno anota lo que los otros nos deben. Los otros no pueden modificar nuestra libreta, y nosotros no podemos modificar la de ellos.

Por otro lado, cuando una deuda está liquidada no arrancamos las hojas, solo marcamos o tachamos la deuda.

Marcar deuda de usuario como pagada

Entonces con eso en mente, solo el autor de la deuda puede marcar que otro usuario ya le ha pagado (con las cajas o checkboxes que aparecen en los deudores), y una vez que lo ha hecho ya no se puede desmarcar.

Por otro lado, cuando se desee se puede liquidar una deuda pero no se elimina, solo se deja de mostrar por defecto. Si queremos ver las deudas liquidadas entonces podemos usar los filtros presentados anteriormente.

Apartado técnico

Esto es una aplicación web creada con Buefy. Le he agregado el manifiesto y he usado Workbox para generar el service worker y convertirla en PWA.

De este modo la app web se puede instalar como si fuera nativa, y funciona totalmente sin conexión; ya sea en computadoras o en móviles.

Los datos se sincronizan en cuanto haya conexión, y podemos usar la app completamente sin internet.

Todo esto es gracias al poder de Firestore Database, solo bastó con habilitar el modo sin conexión:

  const firebaseConfig = {
   apiKey: process.env.VUE_APP_FIREBASE_API_KEY,
   authDomain: process.env.VUE_APP_FIREBASE_AUTH_DOMAIN,
   databaseURL: process.env.VUE_APP_FIREBASE_DATABASE_URL,
   projectId: process.env.VUE_APP_FIREBASE_PROJECT_ID,
   storageBucket: process.env.VUE_APP_FIREBASE_STORAGE_BUCKET,
   messagingSenderId: process.env.VUE_APP_FIREBASE_MESSAGING_SENDER_ID,
   appId: process.env.VUE_APP_FIREBASE_APP_ID,
  };
  const app = initializeApp(firebaseConfig);
  const bd = getFirestore(app);
  if (modoSinConexionActivado) {
   return bd;
  }
  try {
   await enableIndexedDbPersistence(bd);
   Toast.open({
    message: "Modo fuera de línea habilitado correctamente",
    type: "is-success",
   });
   modoSinConexionActivado = true;
  } catch (err) {
   console.log({ err });
   let mensaje = "";
   if (err.code == "failed-precondition") {
    mensaje =
     "Error: recuerda no tener varias pestañas abiertas con la app";
   } else if (err.code == "unimplemented") {
    mensaje =
     "Error: el navegador que usas no soporta el modo fuera de línea. Cambia de navegador";
   }
   mensaje += " " + err.toString();
   Toast.open({
    message: mensaje,
    type: "is-danger",
   });
  }
  return bd;

Descarga del código

Puedes acceder al repositorio desde este enlace. A continuación detallo lo que hay que hacer para tener tu propia versión funcionando.

Preparando entorno de desarrollo

Necesitamos NPM y Node. Si no sabes cómo instalarlos, lee: https://parzibyte.me/blog/2018/09/27/instalar-npm-node-js-windows/

También necesitas crear un proyecto de Firebase (https://firebase.google.com/?authuser=0) y agregarle Firestore, es decir, crea una base de datos y agrega una app web. Ya tengo un tutorial sobre ello que te invito a leer antes de continuar leyendo este.

Recuerda que debes iniciar sesión para poder usar la app, así que primero debes crear un usuario y una contraseña desde la consola de Firebase (ya que la app es inaccesible sin usuarios).

Haz clic en Iniciar colección, en el id coloca usuarios, elige un ID automático y luego coloca los datos de nombre y palabraSecreta.

Las contraseñas están hasheadas con bcrypt así que antes de escribir el valor ve a https://bcrypt-generator.com/, genera un hash a partir de tu contraseña en texto plano y coloca el hash en el campo:

Crear primer usuario para deudas compartidas

Nota: si de verdad se te está complicando, entonces utiliza la siguiente contraseña que es 123: $2a$10$hH75NKoEatMtpmGmuT/ahu380ZZXHllElNUHv10XXpaggDSHzpf0S; al momento de iniciar sesión simplemente coloca la contraseña 123 y el usuario que tú hayas colocado.

Luego de eso debes crear varios índices para la base de datos, esto es para el ordenamiento de datos. Deben quedar así:

Índices de la app de gastos compartidos con Firebase y Firestore Database

Nota: si no creas los índices, no vas a poder filtrar los datos. Incluso Firebase te dirá que esos índices no existen pero que puedes crearlos usando un enlace que aparecerá en la consola de depuración.

Después de eso abre una terminal en donde está el proyecto y ejecuta: npm install

Crea un archivo llamado .env basándote en .env.example y configura las variables del entorno con la firebaseConfig que debiste obtener al crear el proyecto según mi otro tutorial que ya dejé arriba.

Inicia el servidor de desarrollo con npm run serve y visita http://localhost:8080, ahí debería estar la app.

Compilando para producción

La explicación del código y compilación también están disponibles como vídeo en mi canal:

Aviso sobre la seguridad

Quiero dejar algo claro: la app no es segura en cuanto a la autenticación de usuarios si es que los usuarios conocen de informática.

La contraseña sí es almacenada de manera segura y no se puede “desencriptar” (aunque sí es susceptible a ataques de diccionario, pero no existe contraseña que no sea susceptible a eso), pero el proceso de autenticación es totalmente inseguro, ya que simplemente se coloca una bandera en el localStorage; no se maneja autenticación por parte del servidor.

Entonces si el usuario es alguien “confiable” o que no tiene conocimientos del tema puedes dejar la autenticación como está, y si no, puedes hacer los ajustes necesarios en el código.

Yo lo he dejado así porque sé que las personas con las que comparto son confiables. Si los usuarios son personas sin conocimientos informáticos entonces puedes estar tranquilo.

Nota: no utilicé la autenticación de Firebase porque necesitaba tener la lista de todos los usuarios para la app, cosa que no es posible por seguridad de Firebase.

Conclusión

Te dejo con más proyectos open source y gratuitos que he creado. Recuerda que ya te dejé la demostración y el código completo arriba.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

8 horas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

8 horas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

8 horas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

9 horas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

9 horas hace

Solución: Apache – Server unable to read htaccess file

Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…

23 horas hace

Esta web usa cookies.