
Portadilla
Nébula
Tu biblioteca personal inmersiva: importa tus EPUB y viaja.
Diseño de producto, arquitectura y desarrollo completo (app Flutter, Cloud Functions, panel web y panel Android)
v1.0.0 completa y probada en dispositivo; pendiente de publicación en tiendas
Pasa página con ← → o baja
Capítulo uno
Lectores sin biblioteca propia
Las apps de lectura serias son tiendas: viven de venderte su catálogo, atan tus libros a su cuenta y necesitan conexión para casi todo. Quien ya tiene sus EPUB —comprados sin DRM o de dominio público— se queda con lectores austeros que ni recuerdan el progreso decentemente, ni funcionan bien sin internet, ni ayudan a sostener el hábito. Y las que sí gamifican lo hacen empujando a competir con desconocidos, que es exactamente lo contrario de lo que busca alguien que lee para desconectar.
Catálogo ajeno
tus libros atados a una cuenta
Siempre en línea
sin red no hay casi nada
Competir
rankings con desconocidos
Capítulo dos
El contenido lo pone el lector
Nébula invierte el modelo: el contenido lo pone el lector y la app pone todo lo demás. Un EPUB importado se convierte en texto plano que alimenta cuatro modos de consumo —lector paginado, lectura rápida RSVP, escucha por TTS y conversación con la IA Nova— y en la materia prima de la gamificación, porque de las palabras extraídas dependen el progreso, las estrellas y la rareza de las recompensas. Todo lo irremplazable se guarda en Hive dentro del teléfono; la red solo hace falta para lo que de verdad la necesita (la IA, la voz en la nube, la copia de seguridad y los avisos), y cada una de esas puertas degrada con elegancia cuando no hay internet.
Lector
8 temas · 10 tipografías
Lectura rápida
RSVP con letra pivote
Escucha
TTS con sesión de medios
Nova
IA sobre el libro abierto
Capítulo tres
Seis decisiones que no se negocian
Offline-first de verdad
La biblioteca, el progreso, las citas, los resaltados, las estadísticas y toda la gamificación viven en 9 cajas de Hive dentro del teléfono. El modo de lectura rápida es offline duro: sus 8 ambientes visuales y sonoros van dentro del binario y no tiene un solo import de red.
Cuatro formas de leer el mismo libro
Lector paginado con 8 temas, 10 tipografías —Atkinson Hyperlegible incluida para dislexia— y anclaje de resaltados por coordenadas del documento; lectura rápida RSVP palabra a palabra con letra pivote; escucha por TTS con sesión de medios; y Nova, la IA que resume, explica y responde sobre el libro abierto.
Gamificación sin nadie más
76 cosméticos, 32 logros, misiones diarias y semanales, contratos de lectura con apuesta, pase de 50 niveles por temporada, un cielo de constelaciones donde cada libro terminado enciende una estrella y un diario. Ninguna función necesita otro usuario: compartir es exportar una imagen, nunca socializar dentro de la app.
La clave nunca viaja en el APK
Nova empezó llamando a Gemini desde el móvil con la clave embebida. Se movió entera a la Cloud Function novaGenerate, que guarda la clave, elige el modelo y aplica techos por usuario y globales. Firestore está cerrado a cal y canto: las reglas deniegan todo a los clientes y solo entra el Admin SDK.
39 idiomas con paridad verificada
1.929 claves por idioma, cargadas desde JSON sueltos para que añadir una lengua sea dejar caer un archivo. Una prueba recorre los catálogos reales y exige que cada clave derivada en código exista en todos los idiomas: es la que cazó cinco claves de Nova que se construían en tiempo de ejecución y se pintaban en crudo.
Copia de seguridad que no se rinde
Auto Backup de Android estaba roto sin saberlo: sin reglas declaradas respaldaba 109 MB, superaba el límite de 25 MB y dejaba de respaldar en silencio. Ahora respalda los 28 KB que importan, y un archivo .nebula exportable —ZIP versionado con manifiesto— cubre el cambio de plataforma y los EPUB que la nube no puede llevarse.
Lámina desplegable
Cinco pantallas, un mismo cielo
Recreadas en HTML y CSS con la paleta, las medidas y los ritmos reales de la app.
Tu semana lectora
Meta diaria · 24 de 30 min
Favoritos
Ver todoMis libros
El jardín de las horas
M. Arriaga
Cartografía del insomnio
L. Berenguer
Los que miran arriba
T. Okonkwo
Nada que devolver
S. Vidal
Lo primero que se ve: la nebulosa propia, con la semana lectora arriba.
Demostración
Quita la red y no se cae nada
Todo lo irremplazable vive en 9 cajas de Hive dentro del teléfono. La conexión solo hace falta para la IA, la voz en la nube, la copia de seguridad y los avisos: cuatro puertas que degradan con elegancia.
Lector paginado con capítulos, marcadores, búsqueda con salto a página, justificado, márgenes, velo de atenuado propio y menú de selección pegado al texto
Resaltados en 5 colores anclados a coordenadas del documento (párrafo + desplazamiento), inmunes al recálculo de paginación al cambiar letra o márgenes
Lectura rápida RSVP a pantalla completa con letra pivote, fondo Ken Burns temático, partículas y audio ambiental en bucle con fundido entre capítulos
Biblioteca con búsqueda, orden, filtros por estado de lectura, favoritos y estanterías personalizadas con 24 temas ilustrados por Canvas
Bóveda secreta con PIN: los libros ocultos no aparecen en ninguna superficie de la app fuera de la bóveda, ni siquiera en citas, resúmenes o contratos
Pase de temporada de 50 niveles por bimestre con eventos temáticos por calendario
Constelaciones: cada libro terminado se convierte en una estrella con posición estable por hash FNV-1a, agrupada en 8 constelaciones por género
Recordatorios locales de 5 tipos, sin FCM y sin internet, apagados de fábrica y con alarmas inexactas a propósito
Widget de pantalla de inicio en Android que se repinta al volver a primer plano y compara el día guardado con el del sistema
Las cifras
Doce estrellas, un solo cielo
Arrastra el cielo hacia los lados →
Bajo el capó
Tres superficies y una puerta cerrada
Tres superficies sobre un único proyecto Firebase propio (nebula-e30fc). La app Flutter organiza sus 158 archivos Dart en core (tema, rutas, i18n, analítica, widgets), data (modelos Hive con adaptadores escritos a mano), features (una carpeta por módulo, 31 rutas nombradas registradas en main.dart) y services (unos 45 servicios de dominio inyectados con GetX). La persistencia es local por diseño: 9 cajas de Hive guardan libros, sesiones, citas, estanterías, resaltados, marcadores, contratos, diario y una caja meta cuyas claves llevan prefijo obligatorio por módulo (gm_, ct_, sp_, ev_, nv_, cl_, dy_, rn_). El servidor son 26 Cloud Functions en Node 22 repartidas en cuatro módulos —índice (Nova, voz en la nube, pagos manuales y membresías), panel, notificaciones push y correos— sobre 11 colecciones de Firestore. La decisión estructural del backend es que Firestore está cerrado a los clientes: las reglas deniegan todo y el único camino a los datos son las callables, que autorizan con Admin SDK; el panel web y el panel Android son, literalmente, pantallas sin privilegios propios. Nova y la voz en la nube pasan siempre por el servidor para que ninguna clave viaje en el binario, con cuota local en el móvil como pista de interfaz y el techo real aplicado en la función.
Aparato crítico
Seis notas al pie del proyecto
La clave de Gemini viajaba embebida en el APK. Un APK publicado lo descarga cualquiera, y esa clave estaba atada a una cuenta de facturación real: quien la extrajera podía gastar sin límite con cargo al dueño, y ninguna cuota en el móvil lo impide porque el atacante no pasa por el móvil.
Cómo se resolvió
Nova se partió en dos: el servicio del móvil solo compone la petición y la Cloud Function novaGenerate guarda la clave, elige el modelo y aplica un techo por usuario y otro global diario. La API pública del servicio (chat, resumen, personajes, cuestionario, explicar) se mantuvo idéntica, así que ninguna pantalla se enteró del cambio.
Nova dejó de responder de golpe sin haber tocado nada: el modelo gemini-2.5-flash empezó a devolver 404 por ser un proyecto nuevo, y el campo thinkingConfig que se usaba para vaciar el razonamiento pasó a devolver 400. El modelo seguía apareciendo listado en la API pese a rechazar las peticiones.
Cómo se resolvió
Se dejó de fijar un modelo por versión. Ahora hay una cascada de modelos encabezada por un alias que Google mantiene al día, y cada 404 o 400 lanza el reintento con el siguiente, probando cada modelo con y sin ajuste de razonamiento; el que funciona se cachea en memoria. La regla quedó escrita: nunca fijar una versión concreta de modelo en una app publicada.
Resaltar la palabra "que" teñía todas sus apariciones del libro. El primer intento —guardar los 40 caracteres previos como contexto— solo desambiguaba dentro de un párrafo, y como el pintado se aplica bloque a bloque, seguía marcando una aparición en cada párrafo que contuviera la palabra.
Cómo se resolvió
Identificar un resaltado por su texto es ambiguo por definición. Se ancló a coordenadas del documento: índice de párrafo dentro del capítulo más desplazamiento en el párrafo, que no cambian nunca, mientras que la paginación sí se recalcula al tocar letra o márgenes. El controlador de paginación pasó a exponer bloques con esas coordenadas y los párrafos se normalizan siempre, no solo al partirlos.
Android Auto Backup venía activado y estaba roto en silencio: sin reglas declaradas respaldaba el directorio entero, 109 MB de los que unos 106 MB eran assets que ya viajan dentro del APK, se pasaba del límite duro de 25 MB y dejaba de respaldar absolutamente todo sin avisar.
Cómo se resolvió
Se declararon reglas para las dos épocas de Android incluyendo solo lo irremplazable —28 KB de cajas Hive, portadas y preferencias— y excluyendo assets, EPUB y archivos de bloqueo. Verificado en dispositivo: la copia pasó de fallar a completar. Como Auto Backup no puede llevarse los EPUB ni cruzar de plataforma, se añadió además un archivo .nebula exportable y la re-vinculación de libros restaurados sin archivo conservando su identificador.
La capa de gamificación abría agujeros de economía difíciles de ver leyendo el código: firmar y cancelar un contrato inflaba el total histórico de estrellas y el rango, varios contratos idénticos resueltos por la misma sesión funcionaban como impresora, un doble toque en la tienda cobraba dos veces y el modo enfoque seguía pagando con el móvil bloqueado porque medía reloj de pared.
Cómo se resolvió
Revisión adversarial por dimensiones —economía, persistencia, ciclo de vida, integración, interfaz e idiomas— lanzada en tandas pequeñas. De ahí salieron una devolución que repone saldo sin tocar el histórico, el rechazo de contratos equivalentes con tope de activos, un cerrojo de compra y un cronómetro que solo corre en primer plano. Cada agujero quedó fijado por una prueba propia dentro de las 618 del repositorio.
Un panel de administración protegido solo por el correo del dueño no cerraba nada: la clave web del proyecto viaja dentro del APK de los lectores por diseño de Firebase, así que cualquiera podía registrar una cuenta con ese correo mientras no existiera y pedir la verificación, que llega al buzón legítimo del dueño.
Cómo se resolvió
La autorización exige tres condiciones a la vez en el servidor —correo del dueño, correo verificado y UID coincidente con el fijado en configuración— y falla cerrado si no hay administrador fijado. El UID es el que de verdad cierra la puerta. Ninguna contraseña vive en el binario, y hay una prueba en el repositorio que falla si alguna vez aparece un secreto.
Índice
Veintiuna entradas, todas dentro
Importación de EPUB desde el explorador de archivos o compartiendo desde otra app, con re-enlace de libros restaurados sin archivo que conserva progreso, citas y reseña
Lector paginado con capítulos, marcadores, búsqueda con salto a página, justificado, márgenes, velo de atenuado propio y menú de selección pegado al texto
Resaltados en 5 colores anclados a coordenadas del documento (párrafo + desplazamiento), inmunes al recálculo de paginación al cambiar letra o márgenes
Lectura rápida RSVP a pantalla completa con letra pivote, fondo Ken Burns temático, partículas y audio ambiental en bucle con fundido entre capítulos
Escucha por TTS del dispositivo con resaltado del párrafo actual, control de velocidad, temporizador de sueño y controles en la pantalla de bloqueo; voz en la nube opcional por minutos
Nova, la IA lectora: chat sobre el libro, resumen, fichas de personajes, cuestionario y explicación de un fragmento seleccionado
Biblioteca con búsqueda, orden, filtros por estado de lectura, favoritos y estanterías personalizadas con 24 temas ilustrados por Canvas
Bóveda secreta con PIN: los libros ocultos no aparecen en ninguna superficie de la app fuera de la bóveda, ni siquiera en citas, resúmenes o contratos
Economía de estrellas con multiplicador de racha, tope diario medido en minutos y una única puerta de concesión y gasto para evitar el farmeo
Misiones diarias y semanales derivadas de sesiones reales, ruleta ponderada y cofres
Contratos de lectura con apuesta de estrellas, escudo de racha, y modo enfoque cuyo cronómetro solo corre con la app en primer plano
Pase de temporada de 50 niveles por bimestre con eventos temáticos por calendario
Constelaciones: cada libro terminado se convierte en una estrella con posición estable por hash FNV-1a, agrupada en 8 constelaciones por género
Nova como compañera offline de 20 niveles con observatorio, auras, nido y guardarropa por capas dibujado con Canvas
Álbum de cartas por libro con rareza, jardín de 7 fases, insignias secretas, diario de lectura y resúmenes mensual y anual
Tarjetas compartibles de 1080×1920 para citas, logros, progreso, pulso del libro y resumen del año
Recordatorios locales de 5 tipos, sin FCM y sin internet, apagados de fábrica y con alarmas inexactas a propósito
Widget de pantalla de inicio en Android que se repinta al volver a primer plano y compara el día guardado con el del sistema
Copia de seguridad en la nube por lector, exportación manual a archivo .nebula y reglas de Auto Backup y exclusión de iCloud afinadas
Membresía con doble vía: suscripción de tienda y pago manual revisable desde el panel, con detección de doble cobro
Panel web de administración de seis pantallas y panel Android gemelo, ambos hablando solo con las Cloud Functions
Bibliografía
Con qué está escrito
App móvil
Lectura y contenido
Interfaz
Firebase y backend
Identidad y monetización
Sistema y utilidades
Panel web (nebula-web)
Panel Android (nebula-admin)
Láminas
La identidad del proyecto
Onboarding, imagen social y cabecera de los correos que envían las Cloud Functions. Arrastra.





Colofón
Lo que es Nébula
Nébula es un lector de ebooks offline-first para Android e iOS que no trae catálogo: el lector importa sus propios EPUB y la app los convierte en una biblioteca viva, con progreso, citas, resaltados y estadísticas que viven en el teléfono.
Sobre ese lector se monta una capa de hábito completamente individual —estrellas, misiones, contratos de lectura, pase de temporada, constelaciones, cartas y diario— construida bajo una regla dura de producto: nada que requiera otros usuarios, chat ni comparación social.
El ecosistema son tres superficies sobre un mismo proyecto Firebase: la app Flutter (158 archivos Dart, ~99.000 líneas), 26 Cloud Functions en Node 22 y dos paneles de administración, uno web en React y otro Android en Flutter.
Está traducida a 39 idiomas con 1.929 claves por idioma y sostenida por 618 pruebas automatizadas repartidas en 68 archivos, varias de ellas escritas expresamente para fijar agujeros de economía encontrados en revisiones adversariales.
Paleta
#6C4DF4
primary
#4D9FF4
secondary
#22D3EE
accent
#0B0E1D
bg
#141A33
surface
#F2F4FF
text
Cósmico nocturno y editorial: azul de medianoche profundo, violeta de nebulosa y un cian eléctrico que solo se usa para lo que brilla de verdad. Tipografía Sora para leer y Space Mono para las cifras. Es oscuro siempre, a propósito, porque la app se usa de noche y con la cara pegada a la pantalla.
Año
2026
Categoría
App móvil de lectura · Flutter + Firebase
Estado
v1.0.0 completa y probada en dispositivo; pendiente de publicación en tiendas
Un lector que no vende libros: los recibe, los cuida y los convierte en un cielo propio.
Nébula
¿Quieres algo así para tu producto?
Una app offline-first con lector propio, IA servida desde el backend y una capa de hábito que no necesita a nadie más. Si tienes algo así en la cabeza —Flutter, Firebase, producto entero— es exactamente el terreno que conozco.