CliffPickleball
Red social y mensajería cifrada para la comunidad del pickleball
Desarrollador móvil Flutter (arquitectura, integración Firebase, cifrado y capa offline)
Un club repartido y un binario que lo junta
Lado A · el problema
Tres canales para una sola comunidad
Una comunidad deportiva que quiere coordinarse termina repartida entre grupos de WhatsApp, publicaciones de Instagram y hojas de cálculo: no hay un lugar único donde un jugador descubra a otros del club, les envíe una solicitud de conexión, publique lo que está haciendo hoy y converse en privado. Además, un chat de club maneja fotos, vídeos, notas de voz, ubicaciones y contactos que sus miembros no quieren dejar en manos de una plataforma publicitaria, y buena parte de esas conversaciones deben poder leerse aunque el teléfono esté sin señal en la cancha.
Lado B · la solución
Dos módulos, una sesión, cifrado en el teléfono
Se construyó una app Flutter única con dos módulos que comparten sesión de Firebase Auth y navegación: un mensajero privado (pantalla de inicio con buscador, actividades y lista de chats; gestión de conexiones en pestañas Available / Incoming / Sent; conversación con siete tipos de mensaje) y un módulo social con feed, historias, búsqueda, notificaciones y perfil. Cada mensaje y cada actividad se guarda cifrado con AES-CBC en una base sqflite local, de modo que el historial se lee sin conexión, y Firestore actúa solo como canal de sincronización. Las actividades caducan solas: dos tareas periódicas de Workmanager barren cada 15 minutos las que superaron su tiempo de vida y borran a la vez el registro local, el documento en Firestore y el archivo en Firebase Storage.
02 / Marcador
rama dev
82
archivos con widgets de pantalla en lib/screens
31
providers registrados en el MultiProvider raíz
15
colecciones Firestore referenciadas
78
dependencias declaradas en pubspec.yaml
7
tipos de mensaje soportados en el chat
5
tipos de contenido en las actividades
4
tablas cifradas en la base local sqflite
3
modos de tema: sistema, oscuro y claro
Seis golpes que sostienen el peloteo
Cada tarjeta aparece cuando la línea de la pelota la alcanza.
Mensajería con contenido cifrado en el dispositivo
Todo lo que se persiste localmente (mensajes, conexiones, actividades y datos del usuario) pasa por la clase Secure, que aplica AES en modo CBC con relleno PKCS7 antes de escribir en sqflite. La pantalla About lo comunica de forma explícita al usuario.
Chat multiformato con siete tipos de mensaje
Texto, audio grabado en la app, imagen, vídeo con miniatura, documento, ubicación mostrada en Google Maps y contacto de la agenda. Cada opción del panel de adjuntos tiene su propio color de burbuja: cámara morada, galería azul, vídeo celeste, documento rosa, audio ámbar, ubicación verde y contacto naranja.
Actividades efímeras que se limpian solas
Las actividades admiten texto, imagen, vídeo, audio y encuestas de dos o más opciones. Dos tareas periódicas registradas en Workmanager revisan cada 15 minutos las actividades propias y las de las conexiones, y eliminan las expiradas en local, en Firestore y en Storage.
Gestión de conexiones en tres pestañas
Un TabController con las vistas Available, Incoming y Sent, cada una alimentada por su propio provider, permite descubrir usuarios disponibles, aceptar solicitudes recibidas y seguir el estado de las enviadas, con buscador y estado vacío 'Not Found'.
Muro social sobre la misma sesión
Un segundo módulo añade feed de publicaciones, historias con visor y confirmación, búsqueda de usuarios, notificaciones, comentarios, likes y perfil editable, apoyado en colecciones Firestore propias como posts, comments, likes, followers y following.
Tres modos de tema y personalización del chat
ThemeProvider guarda la preferencia en almacenamiento local y resuelve entre modo sistema, oscuro y claro; el usuario elige además wallpaper de chat entre categorías bright, dark, color sólido o sus propias fotos.
Las pantallas, pixel a pixel
Recreadas en HTML y CSS con los colores exactos de lib/config/colors_collection.dart: azul de splash, verde de acción, naranja de contacto y los violetas del chat.
CliffPickleball
Splash
Splash de arranque
Activities
Messages
Home
Inicio: actividades y mensajes
Connection Management
Not Found
Connections
Gestión de conexiones
Chat
Conversación con panel de adjuntos
Settings
Created By Arturo Sojo
Settings · light
Ajustes con selector de tema
← arrastra para recorrer las cinco pantallas →
Y así se ve en el teléfono
Capturas del build de la rama dev corriendo en Android.








Todo lo que ya juega
21 funcionalidades repartidas por la cancha, cada una en su casilla.
Registro e inicio de sesión con correo y contraseña (con verificación por email obligatoria) o con Google Sign-In
Pantalla de introducción, toma de información de perfil y splash animado con el isotipo de la marca
Inicio con buscador, carrusel de actividades y lista de conversaciones recientes
Gestión de conexiones con pestañas de usuarios disponibles, solicitudes recibidas y solicitudes enviadas
Conversación uno a uno con texto, notas de voz, imágenes, vídeos, documentos, ubicación y contactos
Grabación de audio con visualizador de onda y reproducción integrada
Envío de ubicación actual y visualización a pantalla completa sobre Google Maps
Reenvío de mensajes, selección múltiple y borrado remoto mediante operación especial
Creación de actividades efímeras con texto, foto, vídeo, audio o encuesta de opciones múltiples
Visor de actividades con controlador de progreso y resultados de encuesta
Feed social con publicaciones, comentarios, likes, historias y notificaciones
Búsqueda de usuarios y perfiles públicos con seguidores y seguidos
Perfil editable con foto (recorte incluido), nombre, biografía y correo
Ajustes con tema del sistema/oscuro/claro, wallpaper de chat, historial, almacenamiento, soporte, acerca de e invitar a un amigo
Panel de almacenamiento que separa imágenes y vídeos de audios y documentos
Respaldo y restauración del historial de chat
Notificaciones push con Firebase Cloud Messaging y notificaciones locales, con interruptor para activarlas o desactivarlas
Indicador de estado en línea y última conexión sincronizado con el ciclo de vida de la app
Detección de conectividad con aviso cuando no hay red
Menú lateral de navegación entre Messages, Connect, Settings y Videos
Aviso de nueva versión disponible mediante new_version_plus
El vuelo de un mensaje
De la burbuja que escribes al documento que aterriza en Firestore, pasando por el cifrado local.
Interfaz
screens/ · 120 archivos
- entry_screens: splash, intro, registro y toma de datos
- chat, actividades, conexiones y ajustes
- social_media con su propio MVVM (models, services, view_models, widgets)
- MainScreen como shell con Drawer de cuatro destinos
Estado y servicios
providers/ · services/ · auth/
- 31 ChangeNotifier registrados en el MultiProvider raíz
- MainScreenNavigationProvider conmuta el módulo visible
- services: cifrado, base local, permisos, descargas, mapas y navegación
- db_operations con rutas tipadas en DBPath y StorageHelper
Persistencia
sqflite cifrado + Firebase
- 4 tablas locales: usuario, conexiones, chats por conexión y actividades
- Firestore y Storage como canal de sincronización remota
- Workmanager caduca las actividades cada 15 minutos
- Firebase Messaging entrega las notificaciones
Aplicación Flutter monolítica organizada por capas dentro de lib/: config (paleta, textos, estilos, enums y rutas de imágenes), auth (Google y correo), db_operations (acceso a Firestore y Storage con rutas tipadas en DBPath y StorageHelper), providers (31 ChangeNotifier registrados en un MultiProvider raíz), services (cifrado, base de datos local, permisos, descargas, notificaciones, mapas, archivos y navegación) y screens (120 archivos de interfaz). El árbol de pantallas se divide en tres bloques: entry_screens para splash, intro, registro y toma de datos; los módulos de chat, actividades, conexiones y ajustes; y screens/social_media, un módulo con su propia estructura MVVM (models, services, view_models, widgets) para el feed social. MainScreen actúa como shell: mantiene un Drawer con cuatro destinos y un índice en MainScreenNavigationProvider que conmuta entre HomeScreen, ConnectionManagementScreen, SettingsScreen y el módulo social. La persistencia es doble: sqflite guarda cifradas cuatro tablas locales (usuario actual, conexiones, chats por conexión y actividades) para lectura sin conexión, mientras Firestore y Firebase Storage sincronizan el contenido remoto; Workmanager corre tareas en segundo plano para caducar actividades y Firebase Messaging entrega las notificaciones tanto en primer plano como con la app cerrada.
78 dependencias, siete bolsas
Framework y lenguaje
Estado y navegación
Backend y servicios Firebase
Persistencia local y seguridad
Multimedia y contenido
Mapas, dispositivo y sistema
UI y utilidades
Los puntos que costaron el partido
Cinco problemas reales del código y cómo se resolvieron. Toca cada uno para abrirlo.
Cómo se devolvió
Se mantuvo cada módulo con su propio estilo pero se unificó el punto de entrada: un único MultiProvider raíz registra los 31 providers de ambos mundos y MainScreen resuelve por índice qué módulo se muestra, de modo que la sesión de Firebase Auth y el tema se comparten sin reescribir el módulo social.
10 / Paleta de la app
Deportivo y nocturno: azul cancha profundo como base, verde de acción para todo lo interactivo y un naranja de pelota que aparece solo en los acentos. Superficies casi negras con tinte violáceo, tipografía Poppins redondeada y bordes muy generosos que suavizan el contraste.
lib/config/colors_collection.dart (clase AppColors, rama dev): splashScreenColor 0xff0152cd, lightBorderGreenColor 0xff01bd47, backgroundDarkMode 0xff15162d, searchBarBgDarkMode 0xff2e2d42, backgroundLightMode 0xfffefeff, lightModeBlueColor 0xff0186fe y personIconBgColor 0xffF26109, este último coincidente con el naranja del isotipo en assets/images/channels4_profile.jpg
Un club con su propia app, no una carpeta de capturas.
Cliff Pickleball es una aplicación Flutter que reúne en un solo binario dos mundos que normalmente viven separados: un mensajero privado uno a uno con cifrado local y un muro social con publicaciones, historias, seguidores y notificaciones.
El objetivo es dar a un club de pickleball su propio espacio: los jugadores se descubren, se conectan mediante solicitudes, publican actividades efímeras (texto, foto, vídeo, audio o encuesta) y conversan sin depender de una red social de terceros.
El proyecto vive en la rama dev del repositorio; la rama main conserva el esqueleto anterior del proyecto. Todo lo descrito aquí corresponde al código real de dev, que declara 78 dependencias en pubspec.yaml y apoya toda la persistencia remota en un proyecto Firebase propio llamado cliff-pickleball.
La app arranca con un splash azul y el isotipo naranja de la marca, y a partir de ahí ofrece tema claro, oscuro o del sistema, wallpapers de chat, respaldo de historial y un panel de almacenamiento donde el usuario revisa qué media ocupa espacio.
Cliff Pickleball
¿Quieres algo así para tu producto?
Mensajería cifrada en el dispositivo, contenido que caduca solo y un muro social sobre la misma sesión de Firebase. Si tu comunidad necesita su propio espacio en vez de tres grupos de WhatsApp, éste es exactamente el terreno que conozco.