← Todos los proyectos

MaviKekas

App móvil en Flutter para centralizar los pedidos de comida de un equipo — respaldada por un backend serverless en Firebase, con la lógica de integridad viviendo en el servidor, no en el cliente.

FlutterDartFirebaseFirestoreCloud FunctionsRiverpod

Todos los equipos tienen ese chat. El de “¿alguien va a pedir?”, donde cada quien manda por WhatsApp lo que quiere, las órdenes se pierden entre memes y mensajes de otra cosa, y alguien termina haciendo scroll hacia arriba para reconstruir quién pidió qué. MaviKekas nació justo de ese dolor: es una app que hice para mis compañeros y para mí, para dejar de perseguir órdenes en el chat y centralizar el pedido en un solo lugar.

El problema

Pedir comida en grupo no es un problema de comida — es un problema de coordinación. ¿Quién pide hoy? ¿Qué quiere cada quien? ¿Ya cerramos? Cuando todo eso vive en un chat, la información existe pero está dispersa: hay que leer todo el hilo para armar el pedido, y siempre se cuela un “ah, yo también quería” cuando ya lo mandaste al local. Y más allá del pedido del día, faltaba una forma sencilla de proponer “¿nos juntamos tal día a comer todos?” sin abrir otra encuesta improvisada cada vez.

El trabajo de MaviKekas es volver ese desorden un solo flujo: cada quien levanta su orden dentro de una ventana horaria, se consolida sola, y sale un texto listo para pegar en el chat del local.

Qué hace

Pedidos centralizados. Cada persona arma su orden desde la app —sabores, cantidades y, cuando aplica, queso— en lugar de escribirla en el chat. Hay una orden por persona y por día, así que nadie pide dos veces por error, y se puede guardar una orden por defecto para no volver a capturarla cada vez.

Una ventana que se abre y se cierra sola. El pedido solo está disponible dentro de su horario. A la hora de apertura, la app avisa a todo el grupo con una notificación push de “ya se puede pedir”; a la hora de cierre, se cierra el ingreso. Nadie tiene que acordarse de abrir o cerrar nada.

El consolidado, listo para el local. Cuando cierra el pedido, quien administra ve todas las órdenes en tiempo real y genera con un toque un texto formateado listo para copiar y pegar en WhatsApp — el mensaje que de verdad se le manda al local, agrupado y limpio.

Proponer días para comer juntos. Además del pedido diario, cualquiera puede proponer un día especial para reunirse a comer, y el grupo vota (Jalo / Me rajo / Mejor otra cosa). El conteo de la votación se mantiene solo y se comparte como resultado agrupado.

Notificaciones push. Los momentos que importan —se abrió el pedido, hay una propuesta nueva, ya se puede votar— llegan como notificación, para que la app avise a la gente en vez de que la gente tenga que estar revisando la app.

Por dentro

MaviKekas es una app Flutter de un solo código base para Android, iOS y web, sobre un backend 100% serverless en Firebase — sin servidor propio que mantener. Lo interesante no es el CRUD; es dónde vive cada regla.

La lógica de integridad vive en el servidor, no en el cliente. La app replica las reglas para la experiencia (deshabilitar botones, mostrar el estado correcto), pero el control duro está detrás donde un cliente modificado no lo alcanza. Las Security Rules de Firestore revalidan cada escritura: que la orden sea de quien dice ser, que haya una sola por persona y día (con un id determinístico), y que caiga dentro de la ventana horaria — calculada en las propias reglas. Un cliente hackeado no puede colar un pedido fuera de tiempo.

El conteo de votos es autoridad del servidor. Los clientes tienen prohibido escribir el resultado de la encuesta. Cuando alguien vota, una Cloud Function vuelve a leer todos los votos y recalcula el conteo en el servidor, que regresa a todos por streams en tiempo real. Nadie puede inflar una votación desde su teléfono porque el número no lo escribe el teléfono.

Automatización en el backend. Unas Cloud Functions programadas abren y cierran la ventana de pedidos a su hora, y disparan las notificaciones push en los eventos clave (pedido abierto, propuesta creada, votación lista). El cliente nunca controla lo que no debería.

Arquitectura limpia con Riverpod. El código es feature-first: cada módulo sigue el mismo patrón de tres capas —UI → provider (Riverpod) → service → Firebase— con modelos inmutables y dependencias inyectadas por constructor. Casi toda la UI es reactiva vía streams de Firestore, así que la orden propia, el consolidado y las encuestas se actualizan solos.

El stack

  • App — Flutter (Dart) con Material 3, un solo código para Android, iOS y web.
  • Estado — Riverpod (providers → services → Firestore) con inyección de dependencias.
  • Datos — Cloud Firestore como única base de datos, con Security Rules como control de acceso real.
  • Auth — Firebase Auth (email/password), con roles (admin/usuario) verificados en las reglas, no solo en la UI.
  • Backend activo — Cloud Functions (Node) para automatizar apertura/cierre, recalcular el conteo de votos y enviar push.
  • Notificaciones — Firebase Cloud Messaging (FCM), en web y móvil.

Lo que vale la pena resaltar

MaviKekas es un proyecto personal, no un producto comercial — y esa es justamente la gracia. Salió de un problema cotidiano real de mi equipo y resolvió ese problema. Pero como pieza de ingeniería demuestra lo que importa: Flutter multiplataforma end to end, una arquitectura serverless con Firebase bien puesta, y la decisión — la de verdad importante— de poner la lógica de integridad en el servidor (Security Rules y Cloud Functions) en lugar de confiar en el cliente.

Es product thinking que arranca de un dolor real: ver un problema chiquito y cotidiano, y en vez de aguantarlo, construir algo que lo quita.

¿Un café y platicamos?

¿Te gustó lo que leíste? Construyo productos así de punta a punta — y siempre estoy para una buena plática. Hablemos del tuyo, o nomás intercambiamos ideas con un café.