Cómo integrar notificaciones push y comunicación en tiempo real en una app a medida
He pasado por esto tres veces en producción, y siempre llega el mismo punto. La app funciona, el backend responde, todo va sobre HTTP clásico y, de repente, alguien en una reunión dice: «necesitamos que el operario vea el cambio sin pulsar F5». A partir de ahí, el modelo petición-respuesta ya no te sirve. Un usuario manda un mensaje y espera que el otro lo lea ya. Un panel de operaciones que tarda treinta segundos en refrescarse deja de ser un panel y se convierte en un informe. Cuando tu software tiene que reaccionar en milisegundos, hay que poner sobre la mesa WebSockets, SSE, push, brokers de mensajería y unas cuantas decisiones que cuesta deshacer si las tomas mal.
Los datos lo respaldan. Airship publicó en 2024 que las apps con notificaciones push personalizadas retienen un 92 % más que las que no las usan. Ably Technologies lleva años repitiendo el mismo umbral psicológico: por debajo de 200 ms de latencia, el usuario percibe la interacción como instantánea; por encima, nota que está esperando algo. Ese número se queda grabado cuando lo cruzas con tus propias gráficas de Datadog.
Vamos al grano. Este artículo cubre las tres tecnologías de transporte que de verdad usamos hoy, cuándo elegir cada una, qué arquitectura de backend monto cuando alguien me lo pide en pizarra y qué obligaciones de RGPD aparecen en cuanto envías el primer push.
Long polling, SSE y WebSockets: tres caminos hacia el tiempo real
Antes de tocar Firebase o instalar nada, conviene tener claros los tres mecanismos que permiten que el servidor empuje datos al cliente. Cada uno tiene su sitio y, créeme, mezclarlos sin criterio es el origen del 80 % de los problemas que veo en code reviews.
Long polling
El abuelo. El cliente abre una petición HTTP normal; el servidor la deja colgada hasta que tiene algo que decir. Cuando contesta, el cliente abre otra. Repetir.
- Latencia típica: entre 300 ms y varios segundos, según implementación y carga.
- Ventaja: funciona con cualquier infraestructura HTTP. No necesita proxies especiales, no choca con firewalls corporativos paranoicos, no hay handshake exótico.
- Inconveniente: cada ciclo abre y cierra una conexión TCP completa, con cabeceras HTTP, TLS y todo el overhead. Si tienes diez mil usuarios concurrentes, el coste en CPU y memoria se sale del presupuesto.
Sigue siendo útil como fallback cuando un proxy corporativo decide que las conexiones WebSocket son sospechosas y las corta. En 2026, casi nadie lo elige como primera opción, pero te sorprendería ver cuántas implementaciones de producción acaban activándolo en silencio cuando el WebSocket falla.
Server-Sent Events (SSE)
SSE mantiene una conexión HTTP abierta, unidireccional, por la que el servidor empuja texto. El navegador trae EventSource de serie, así que el código de cliente cabe en quince líneas.
- Latencia típica: entre 50 y 150 ms desde que se genera el evento hasta que llega al cliente.
- Ventaja: se monta encima de HTTP/2 sin esfuerzo, aprovecha la multiplexación de streams y la reconexión automática viene en la especificación. Si tu infraestructura ya habla HTTP/2 con un Nginx delante, no tienes que tocar casi nada.
- Inconveniente: unidireccional. Si el cliente también necesita escribir al servidor en tiempo real, tendrás que combinar SSE con peticiones HTTP normales. No es drama, pero ya tienes dos canales que mantener coherentes.
SSE encaja como un guante en paneles de control, feeds de actividad, tickers de precios, dashboards de logística. Si llegaste aquí buscando WebSockets para mostrar el estado de un pedido y nada más, ahórrate la complejidad y monta SSE. Lo agradecerás en la primera incidencia de madrugada.
WebSockets
Conexión TCP bidireccional y persistente. Tras un handshake HTTP de upgrade, hablas en un protocolo propio con frames ligeros.
- Latencia típica: entre 20 y 80 ms. La más baja de las tres.
- Ventaja: bidireccional, overhead mínimo (entre 2 y 14 bytes de cabecera por frame, frente a los varios cientos de una petición HTTP). Es lo que quieres para chats, editores colaborativos, juegos y cualquier cosa donde ambas partes escriben con frecuencia.
- Inconveniente: la infraestructura intermedia tiene que aguantar conexiones largas. Algunos load balancers tienen el timeout en 60 segundos por defecto (mirándote a ti, ALB de AWS sin configurar el idle timeout), y ciertos proxies corporativos cierran conexiones que llevan demasiado tiempo abiertas. La primera vez que un cliente te diga «se desconecta sin razón» y resulte que su firewall cortaba a los cinco minutos, recordarás esta frase.
Tabla comparativa rápida
| Criterio | Long polling | SSE | WebSockets |
|---|---|---|---|
| Dirección | Unidireccional | Unidireccional | Bidireccional |
| Latencia media | 300-2000 ms | 50-150 ms | 20-80 ms |
| Overhead por mensaje | Alto (cabeceras HTTP completas) | Medio | Bajo (2-14 bytes) |
| Reconexión automática | Manual | Nativa | Manual (con librerías) |
| Soporte navegadores | Universal | Todos excepto IE | Todos excepto IE |
| Complejidad de infraestructura | Baja | Baja | Media-alta |
Firebase Cloud Messaging y los servicios gestionados de push
Aquí toca distinguir dos cosas que se confunden mucho en reuniones: la comunicación en tiempo real dentro de la app (la pestaña está abierta, el usuario está mirando) y las notificaciones push que llegan al móvil aunque la app esté cerrada o el dispositivo bloqueado. Son problemas distintos con soluciones distintas.
Firebase Cloud Messaging (FCM) es el estándar de facto para mandar push a Android, iOS y también web vía Push API. Google declaró en 2024 que FCM procesa más de 3 billones de mensajes diarios. Si llegaste aquí desde Firebase y solo necesitas mandar push, no le des más vueltas: úsalo. Si necesitas tiempo real bidireccional dentro de la app, FCM no es tu herramienta y no debería serlo.
Cómo funciona FCM (sin sorpresas)
- El dispositivo se registra en FCM y obtiene un token único.
- Tu backend guarda ese token asociado al usuario (y aquí ya hay decisiones de RGPD que aclaramos más abajo).
- Cuando hay que notificar, tu servidor llama a la API de FCM con el token o con un tema.
- FCM lo enruta: APNs si es iOS, canal directo si es Android.
La latencia media ronda los 250-500 ms. En dispositivos con conectividad intermitente o con Doze mode activo, sube a varios segundos. Y sí, si el fabricante chino del móvil del cliente ha decidido matar tu app en background «para ahorrar batería», la notificación llegará tarde o no llegará. No es tu bug. Documenta el comportamiento esperado en producción antes de que el cliente lo descubra en mitad de una demo.
Alternativas a FCM
- Amazon SNS: integración natural con AWS. 0,50 USD por millón de notificaciones móviles. Si todo tu stack está en AWS, evita el salto a Google.
- OneSignal: capa por encima de FCM y APNs con segmentación, A/B testing y analítica decente. Plan gratuito hasta 10.000 suscriptores. Útil cuando marketing pide funcionalidades que no te apetece construir.
- Pusher / Ably: servicios gestionados que combinan WebSockets y push con SDKs para varias plataformas. Más caros, pero te ahorran montar y operar la mitad de lo que cuento en la siguiente sección.
La elección suele caer por gravedad: tu stack actual decide más que ninguna comparativa. Si ya usas Firebase para auth y Firestore, FCM no se discute. Si tu equipo de DevOps vive en AWS, SNS reduce fricción operativa y un proveedor menos en el inventario de cumplimiento.
Arquitectura pub/sub: el corazón del tiempo real a escala
Da igual qué transporte elijas. Si la lógica que decide qué se envía y a quién está acoplada a tu API, la primera vez que tengas que escalar te encontrarás con un nudo. Aquí entra pub/sub, y aquí es donde la diferencia entre una arquitectura que envejece bien y otra que toca rehacer en dos años se decide en un par de tardes de diseño.
El patrón básico
Los publishers no mandan datos directamente a los suscriptores. Publican mensajes en canales o temas. Los suscriptores se apuntan a los canales que les interesan y reciben lo que llega.
Esa separación trae tres cosas buenas:
- Desacoplamiento: el servicio que genera el evento no sabe (ni le importa) quién lo consume.
- Escalabilidad: añadir un consumidor más no requiere tocar el productor.
- Resiliencia: si un suscriptor se cae, los mensajes pueden quedarse en cola hasta que vuelva.
Herramientas para implementar pub/sub
Redis Pub/Sub es la entrada más rápida. Como broker, vuela: latencias por debajo de 1 ms en local. El problema serio es que no persiste. Si el suscriptor no está conectado cuando se publica el mensaje, ese mensaje se pierde y no hay forma de recuperarlo. Para muchos casos vale; para otros es un fallo silencioso que aparece en producción cuando el cliente más se queja.
Apache Kafka resuelve la persistencia. Log distribuido, los consumidores leen desde el offset que quieran, replays gratis. Es la herramienta de LinkedIn, Uber y Netflix por algo. Un clúster bien configurado pasa de 2 millones de mensajes por segundo con latencias por debajo de 10 ms (Confluent, 2024). El coste es operativo: Kafka quiere ZooKeeper o KRaft, particiones bien pensadas y un equipo que sepa diagnosticar un consumer lag de madrugada.
RabbitMQ está en el medio. Soporta varios patrones (pub/sub, colas de trabajo, routing por temas), persiste mensajes, da confirmaciones de entrega. 30.000-50.000 mensajes por segundo por nodo. Cómodo cuando necesitas garantías de entrega más estrictas y no te apetece operar Kafka.
Google Cloud Pub/Sub y Amazon SNS/SQS son las opciones gestionadas. Pagas por mensaje y te olvidas del broker (Google Pub/Sub cobra 40 USD por TiB publicado). En equipos pequeños esto compensa el primer año casi seguro. Cuando el volumen crece, vuelve a tocar hacer números.
Una arquitectura tipo para una app a medida
El esquema que monto casi siempre cuando un cliente me dice «necesitamos tiempo real» tiene cuatro piezas claras:
- Capa de aplicación: tu API REST o GraphQL gestiona lógica de negocio. Sin cambios bruscos respecto a lo que ya tienes.
- Broker de mensajes (Redis o Kafka): cuando la API genera un evento (pedido nuevo, cambio de estado, mensaje de chat), lo publica en el broker.
- Servicio de WebSocket/SSE: un proceso aparte mantiene las conexiones abiertas con los clientes, se suscribe a los canales del broker y reenvía. Esto va separado de la API por una razón muy concreta: las conexiones largas y los reinicios frecuentes no se llevan bien.
- Servicio de push: otro proceso se suscribe a los mismos canales y dispara FCM/APNs para los dispositivos que tienen la app cerrada.
La ventaja se ve cuando hay que escalar. Si tienes 50.000 WebSockets simultáneos pero solo 1.000 peticiones API por minuto, dimensionas el servicio de socket con más nodos y dejas la API tal cual. Si vienes de una arquitectura donde todo vive en el mismo proceso, este desacoplamiento es lo primero que te ahorra dinero en el siguiente trimestre.
Buenas prácticas de UX para notificaciones
Poder mandar notificaciones en tiempo real no es excusa para mandarlas. Un sistema de push mal diseñado provoca exactamente lo contrario de lo que buscas: el usuario desactiva permisos, te desinstala o, peor aún, asocia tu marca con ruido. Esto último cuesta más de revertir que un bug crítico.
Segmentación y relevancia
No todos los eventos merecen un push. Filtro mental sencillo: ¿el usuario necesita actuar sobre esto ahora? Si la respuesta es no, una notificación in-app o un badge en el icono suele bastar.
Braze publicó en 2024 que las apps que segmentan por comportamiento del usuario logran tasas de apertura un 300 % superiores a las que mandan envíos masivos sin criterio. El número da risa hasta que ves cómo se traduce en tu propia gráfica de retención a 30 días.
Frecuencia y agrupación
Diez notificaciones en una hora sobre el mismo tipo de evento es una receta para la desinstalación. Implementa batching: consolida eventos similares en una sola notificación. Android 13+ e iOS 15+ ya agrupan por app, pero el contenido es más útil si tu backend lo pre-procesa. «Tienes 4 nuevos mensajes de Pedro» rinde mejor que cuatro notificaciones idénticas seguidas. Mide los unsubscribes después de cambiarlo y entenderás por qué insisto.
Canales de notificación
Android, desde la 8.0, permite crear canales que el usuario gestiona uno a uno. Aprovéchalo. Un usuario puede querer alertas de pedidos pero no avisos de marketing. Si los metes todos en el mismo canal, el día que silencie uno los silencia todos, y ahí pierdes también los críticos.
Timing y zonas horarias
Si tu app opera en varias regiones, programa según la hora local del usuario, no la del servidor. Un recordatorio a las 3:00 de la madrugada no solo es inútil: es la causa típica de que el usuario revoque permisos para siempre. Y «para siempre», en iOS, significa que tendrás que ir a Ajustes a recuperarlo manualmente. Nadie lo hace.
Contenido accionable
Cada notificación debería traer suficiente contexto para que el usuario decida si abre la app. «Nuevo mensaje» es peor que «Pedro García ha respondido a tu consulta sobre el presupuesto Q3». Y si el sistema operativo lo permite, mete acciones rápidas: «Marcar como leído», «Responder», «Archivar». El usuario que resuelve sin abrir la app vuelve más veces que el que tiene que entrar para descubrir que no era para tanto.
Cumplimiento del RGPD en notificaciones push
El RGPD y la LSSI-CE marcan cómo implementas las push. Ignorarlas puede salir por hasta 20 millones de euros o el 4 % de la facturación global anual. No es teoría: la AEPD lleva varios años publicando sanciones por consentimiento mal recogido en apps móviles.
El token de push como dato personal
El token FCM o APNs que identifica un dispositivo es dato personal según el criterio de la AEPD: permite dirigir comunicaciones a una persona identificable. Tratarlo requiere base jurídica válida, y eso vale tanto para producción como para entornos de pre.
Consentimiento explícito y previo
Para notificaciones comerciales o promocionales necesitas consentimiento explícito antes del primer envío. Ese consentimiento tiene que ser:
- Libre: no puedes condicionar el uso de la app a aceptar push.
- Específico: el usuario debe saber qué tipo de notificaciones recibirá.
- Informado: quién las envía, con qué finalidad y cómo revocar.
- Inequívoco: acción afirmativa. Casilla no premarcada. Si tu UX tiene un toggle activado por defecto, vas a tener una conversación incómoda con tu DPO.
Notificaciones transaccionales vs. comerciales
Las notificaciones ligadas a un servicio contratado (confirmación de pedido, cambio de estado de un envío, alerta de seguridad) pueden ampararse en ejecución de contrato o interés legítimo, siempre que sean estrictamente necesarias para prestar el servicio. Las comerciales requieren consentimiento siempre. Dibujar esa línea con claridad en una matriz de finalidades te ahorra discusiones recurrentes con legal.
Implementación técnica del consentimiento
En la práctica, el flujo que defiendo siempre tiene dos pasos:
- Permiso del sistema operativo: iOS y Android muestran un diálogo nativo. Este permiso técnico no sustituye el consentimiento RGPD.
- Consentimiento RGPD: una pantalla propia donde el usuario acepta o rechaza tipos concretos de notificaciones, con enlace a la política de privacidad.
Guarda el registro del consentimiento con marca temporal, versión de la política aceptada e identificador del usuario. Si revoca, deja de enviarle push y borra su token de tu base en un plazo razonable. «Razonable» es lo que tú puedas justificar ante una auditoría con cara de no estar improvisando.
Consideraciones de implementación y rendimiento
Gestión de conexiones a escala
Un Node.js con la librería ws aguanta entre 50.000 y 100.000 conexiones WebSocket simultáneas en una instancia con 4 GB de RAM, según benchmarks de la comunidad. Si necesitas más, Socket.IO con adaptador Redis distribuye conexiones entre varias instancias manteniendo coherencia de canales. Aviso por experiencia propia: el adaptador Redis funciona bien hasta que te das cuenta de que un bug puntual genera una tormenta de mensajes que satura el broker. Monitoriza el throughput del adaptador desde el día uno.
Para cargas extremas, modelos de concurrencia como los de Go o Elixir rinden mucho mejor por instancia. Phoenix (Elixir) demostró en 2023 sostener 2 millones de conexiones WebSocket simultáneas en un solo nodo con 128 GB de RAM. Salvo que vendas mensajería a escala global, lo más probable es que no llegues a ese umbral; pero saber que existe el camino te da margen para defender una decisión de stack frente a un comité técnico.
Heartbeat y detección de desconexiones
Las conexiones WebSocket pueden morir en silencio cuando un móvil pierde cobertura sin cerrar limpiamente (el clásico túnel del metro). Implementa heartbeat: el servidor manda un ping cada 25-30 segundos y espera un pong. Si no llega en dos ciclos seguidos, cierras la conexión y liberas recursos. Sin esto, descubrirás un día que tienes 40.000 «conexiones activas» que llevan media hora muertas y están consumiendo memoria.
Reconexión con backoff exponencial
Cuando el cliente detecta desconexión, reintenta con backoff exponencial: 1.000 ms el primer intento, 2.000 ms el segundo, 4.000 ms el tercero, hasta un máximo de 30 segundos. Añade jitter aleatorio (±20 %) para evitar que miles de clientes intenten reconectarse a la vez tras una caída del servidor. Este efecto «thundering herd» es de los que tumban un cluster justo cuando intentas levantarlo, y la cara que pones la primera vez no se olvida.
Cola de mensajes perdidos
Si un cliente se desconecta y pierde mensajes, hace falta que los recupere al volver. Las opciones que veo en producción:
- Last Event ID (SSE): SSE incluye un
idpor evento. Al reconectarse, el cliente manda la cabeceraLast-Event-IDy el servidor reenvía lo posterior. Lo más limpio si ya estás con SSE. - Offset en Kafka: cada consumidor mantiene su offset. Al reconectarse, reanuda desde ahí. Imbatible para auditoría y replays.
- Buffer en Redis: guarda los últimos N mensajes por canal en una lista Redis con TTL. Al reconectarse, el cliente pide lo que le falta. Pragmático y barato.
Del requisito técnico al valor de negocio: llevar el tiempo real a tu aplicación
La comunicación en tiempo real y las notificaciones push no son caprichos técnicos. Son decisiones de producto que mueven métricas de negocio. Una plataforma de logística que notifica los cambios de estado al instante reduce llamadas al soporte. Un CRM que muestra interacciones del equipo comercial en tiempo real evita que dos vendedores llamen al mismo prospecto en el mismo día. Un sistema de alertas que avisa de incidencias en segundos en lugar de minutos es la diferencia entre un susto y una parada de producción.
La clave está en diseñar con criterio: elegir el transporte adecuado, montar pub/sub que escale con el negocio, respetar las preferencias del usuario para no convertir las notificaciones en ruido y cumplir con el RGPD para no llevarse la sorpresa de la sanción.
Si tu equipo está mirando cómo añadir tiempo real a una app existente o cómo diseñar una nueva con estos requisitos desde el inicio, en Tangram Consulting acompañamos a pymes españolas a definir la arquitectura, elegir herramientas y llevar la implementación con un enfoque pragmático: lo que necesitas, con la complejidad que puedes operar, al coste que tiene sentido para tu escala.
Saber cómo integrar notificaciones push y comunicación en tiempo real en una app a medida no consiste en montar la infraestructura más sofisticada; consiste en entender qué eventos merecen llegar al instante, cuáles pueden esperar y cuáles no necesitan notificarse en absoluto. Esa decisión, tomada con cabeza al principio del proyecto, marca la diferencia entre una app que el usuario agradece y otra que silencia el primer fin de semana.