Cliff Pickleball
App móvil social y de mensajería

CliffPickleball

Red social y mensajería cifrada para la comunidad del pickleball

2024 – 2025Prototipo funcional en rama dev, probado en Android

Desarrollador móvil Flutter (arquitectura, integración Firebase, cifrado y capa offline)

01 / El partido

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

03 / Golpes

Seis golpes que sostienen el peloteo

Cada tarjeta aparece cuando la línea de la pelota la alcanza.

01

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.

02

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.

03

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.

04

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'.

05

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.

06

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.

04 / En la cancha

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.

TM

CliffPickleball

Splash

Splash de arranque

9:41▮▮▮ ⌁
CliffPickleball
Search

Activities

ASArturo so…MGMaría g…JPJuan p…

Messages

MGMaría g🗺️ Location10:26
JPJuan pNos vemos en la 309:14
CLCliff🎵 AudioAyer

Home

Inicio: actividades y mensajes

9:41▮▮▮ ⌁
CliffPickleball

Connection Management

AvailableIncomingSent
Search

Not Found

Connections

Gestión de conexiones

9:41▮▮▮ ⌁
MGMaría gonline
¿Jugamos a las 6 en la cancha 3?6:02 PM
Va. Te mando la ubicación del club6:03 PM
🗺️ Location6:03 PM
🎵 Audio · 0:126:05 PM
CameraGalleryVideoDocumentAudioLocationContact
Type a message

Chat

Conversación con panel de adjuntos

9:41▮▮▮ ⌁
CliffPickleball

Settings

App theme
System ThemeDark ThemeLight Theme
Profile
Settings
Chat WallPaper
Chat History
Storage
Support
About
Invite a Friend

Created By Arturo Sojo

Settings · light

Ajustes con selector de tema

← arrastra para recorrer las cinco pantallas →

05 / Capturas

Y así se ve en el teléfono

Capturas del build de la rama dev corriendo en Android.

Splash azul #0152CD con el isotipo naranja sobre placa blanca y el nombre CliffPickleball en blanco
Splash azul #0152CD con el isotipo naranja sobre placa blanca y el nombre CliffPickleball en blanco
Pantalla de inicio en modo oscuro con buscador, sección Activities y lista de Messages
Pantalla de inicio en modo oscuro con buscador, sección Activities y lista de Messages
Connection Management con las pestañas Available, Incoming y Sent y estado vacío Not Found
Connection Management con las pestañas Available, Incoming y Sent y estado vacío Not Found
Ajustes en modo oscuro: App theme, Profile, Settings, Chat WallPaper, Chat History, Storage, Support, About e Invite a Friend
Ajustes en modo oscuro: App theme, Profile, Settings, Chat WallPaper, Chat History, Storage, Support, About e Invite a Friend
Los mismos ajustes en modo claro con el selector de tema desplegado: System, Dark y Light Theme
Los mismos ajustes en modo claro con el selector de tema desplegado: System, Dark y Light Theme
Perfil con avatar circular de borde verde, botón de cámara y campos Name, About y Email editables
Perfil con avatar circular de borde verde, botón de cámara y campos Name, About y Email editables
Ajustes internos con el interruptor de notificaciones en primer plano y en segundo plano
Ajustes internos con el interruptor de notificaciones en primer plano y en segundo plano
Pantalla About explicando el cifrado de mensajes y actividades, con títulos en verde sobre fondo #15162D
Pantalla About explicando el cifrado de mensajes y actividades, con títulos en verde sobre fondo #15162D
06 / El punto completo

Todo lo que ya juega

21 funcionalidades repartidas por la cancha, cada una en su casilla.

01

Registro e inicio de sesión con correo y contraseña (con verificación por email obligatoria) o con Google Sign-In

02

Pantalla de introducción, toma de información de perfil y splash animado con el isotipo de la marca

03

Inicio con buscador, carrusel de actividades y lista de conversaciones recientes

04

Gestión de conexiones con pestañas de usuarios disponibles, solicitudes recibidas y solicitudes enviadas

05

Conversación uno a uno con texto, notas de voz, imágenes, vídeos, documentos, ubicación y contactos

06

Grabación de audio con visualizador de onda y reproducción integrada

07

Envío de ubicación actual y visualización a pantalla completa sobre Google Maps

08

Reenvío de mensajes, selección múltiple y borrado remoto mediante operación especial

09

Creación de actividades efímeras con texto, foto, vídeo, audio o encuesta de opciones múltiples

10

Visor de actividades con controlador de progreso y resultados de encuesta

11

Feed social con publicaciones, comentarios, likes, historias y notificaciones

12

Búsqueda de usuarios y perfiles públicos con seguidores y seguidos

13

Perfil editable con foto (recorte incluido), nombre, biografía y correo

14

Ajustes con tema del sistema/oscuro/claro, wallpaper de chat, historial, almacenamiento, soporte, acerca de e invitar a un amigo

15

Panel de almacenamiento que separa imágenes y vídeos de audios y documentos

16

Respaldo y restauración del historial de chat

17

Notificaciones push con Firebase Cloud Messaging y notificaciones locales, con interruptor para activarlas o desactivarlas

18

Indicador de estado en línea y última conexión sincronizado con el ciclo de vida de la app

19

Detección de conectividad con aviso cuando no hay red

20

Menú lateral de navegación entre Messages, Connect, Settings y Videos

21

Aviso de nueva versión disponible mediante new_version_plus

07 / Cómo está armado

El vuelo de un mensaje

De la burbuja que escribes al documento que aterriza en Firestore, pasando por el cifrado local.

1

Se escribe

screens

ChatScreen · 7 tipos de mensaje

2

Notifica

providers

31 ChangeNotifier en el MultiProvider

3

Se cifra

services

clase Secure · AES-CBC + PKCS7

4

Se guarda

local

sqflite · 4 tablas cifradas

5

Se sincroniza

firebase

Firestore + Storage por par de usuarios

6

Se avisa

firebase

FCM en primer plano y con la app cerrada

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.

08 / Equipación

78 dependencias, siete bolsas

Framework y lenguaje

Flutter (SDK Dart ^3.5.2)Material DesignGoogle Fontsfuente Poppins empaquetada

Estado y navegación

providerflutter_riverpodflutter_blocgo_routerroutemasterpage_transitionanimationssizervelocity_x

Backend y servicios Firebase

firebase_corefirebase_authcloud_firestorefirebase_storagefirebase_messagingfirebase_app_checkgoogle_sign_in

Persistencia local y seguridad

sqfliteshared_preferencesencrypt (AES-CBC/PKCS7)path_providerflutter_dotenv

Multimedia y contenido

image_pickerimage_cropperphoto_viewvideo_playerjust_audiorecordfile_pickercached_network_imagelottiestoryany_link_previewflutter_linkify

Mapas, dispositivo y sistema

google_maps_fluttergeolocatorgeocodinglocationpermission_handlerdevice_info_plusconnectivity_pluscontacts_serviceworkmanagerflutter_local_notificationsshare_plusurl_launchernew_version_plus

UI y utilidades

chat_bubblesflutter_chat_bubbleswipe_tolike_buttonpercent_indicatorsmooth_page_indicatorpull_to_refreshdotted_borderflutter_colorpickerawesome_dialogloading_overlayflutter_spinkitfluttertoastfont_awesome_flutterioniconsflutter_font_iconstimeagointluuidfpdartequatablelogger
09 / Bola muerta

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

#0152CDsplashScreenColor#0186FElightModeBlueColor#01BD47lightBorderGreenColor#F26109personIconBgColor#15162DbackgroundDarkMode#2E2D42searchBarBgDarkMode#FEFEFFbackgroundLightMode

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.

AES-CBC + PKCS7sqflite offlineWorkmanager cada 15 minFirestoreFirebase StorageFCMGoogle Sign-In7 tipos de mensajeAES-CBC + PKCS7sqflite offlineWorkmanager cada 15 minFirestoreFirebase StorageFCMGoogle Sign-In7 tipos de mensaje

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.

FCM verificación por correo perfil editable