Una notificación push es un mensaje iniciado en el servidor que los servicios de push de la plataforma entregan al dispositivo, incluso con la app cerrada. Los equipos de producto conocen el push como canal de engagement; esta entrada cubre la maquinaria de entrega — porque la maquinaria explica cada rareza de la que los equipos de producto se quejan. El hecho central: tu servidor nunca habla con el teléfono. Cada sistema operativo móvil mantiene exactamente una conexión persistente, optimizada para batería, con los gateways de push de iOS y Android (APNs, FCM) — y cada notificación de cada app viaja por esa tubería compartida.
Puntos clave
| Pregunta | Respuesta |
|---|---|
| La cadena | Tu backend → APNs/FCM → el único socket persistente del SO → la app |
| La dirección | Token de dispositivo — por instalación, siempre cambiante, hay que sincronizarlo y podarlo |
| El contrato | Best-effort: aceptado ≠ entregado, limitado, desactivable por el usuario |
| Los límites | Payloads de ~4 KB · flags de prioridad · pushes silenciosos con un presupuesto horario mínimo |
| vs. sockets | El push alcanza apps cerradas; los WebSockets sirven a las abiertas |
La cadena de entrega, de punta a punta
1 La app le pide al SO registrarse para push
2 El servicio de push de la plataforma emite un DEVICE TOKEN (la dirección)
3 La app envía el token a TU backend, que lo almacena
4 Algo sucede → el backend hace POST de { token, payload ≤4 KB } a APNs / FCM
5 El servicio de push encuentra la conexión persistente del dispositivo → entrega
6 El SO muestra la notificación — o despierta la app brevemente si el push es silencioso
El segundo trabajo de FCM: con las credenciales de APNs cargadas, acepta una
solicitud y reemite una solicitud compatible con APNs para los dispositivos iOS —
una sola superficie de API para ambas plataformas. Un BaaS abstrae incluso eso.
Ambas mitades en código — el cliente registrando su dirección, el backend enviando a un canal:
// JavaScript — Cloud Code (cloud/main.js)
// One send call reaches both platform push services
await Parse.Push.send({
channels: ['scores'], // or `where:` with an Installation query
data: {
alert: 'Kickoff! Follow the match live.',
badge: 'Increment',
uri: 'app://match/8fk2',
},
}, { useMasterKey: true });
// Back4app routes to APNs for Apple devices and FCM for Android — one API // Flutter / Dart — Back4app Flutter SDK
// Register this install for push: token + channels live in an Installation
final installation = await ParseInstallation.currentInstallation();
installation
..set('channels', ['scores']) // subscribe to a topic-like channel
..set('user', currentUser); // enables targeting by user later
await installation.save();
// deviceToken and deviceType are captured automatically — your backend
// now addresses this device without touching APNs or FCM directly. // iOS / Swift — Back4app Swift SDK
// Register this install for push: token + channels live in an Installation
var installation = ParseInstallation.current
installation?.channels = ["scores"] // topic-like channel
installation?.user = currentUser // enables targeting by user later
try await installation?.save()
// deviceToken and deviceType are captured automatically — your backend
// now addresses this device without touching APNs directly. // Android / Kotlin — Back4app Android SDK
// Register this install for push: token + channels live in an Installation
val installation = ParseInstallation.getCurrentInstallation()
installation.put("channels", listOf("scores")) // topic-like channel
installation.put("user", ParseUser.getCurrentUser()) // target by user later
installation.saveInBackground()
// deviceToken and deviceType are captured automatically — your backend
// now addresses this device without touching the push services directly. Tokens de dispositivo: la dirección que no deja de cambiar
El ciclo de vida del token es el verdadero trabajo del backend, y la parte que las páginas explicativas se saltan. Registrar: el SO emite un token por instalación de la app. Almacenar: la app lo sincroniza con tu backend en cada arranque — los tokens cambian con reinstalaciones, restauraciones y limpiezas de datos, en silencio. Direccionar: los envíos apuntan a tokens, individualmente o vía el registro. Invalidar: los envíos a tokens muertos vuelven con errores específicos — 410 Gone de APNs, errores de token no registrado de FCM — y FCM considera obsoletos los tokens sin uso durante unos nueve meses. Podar: borra al ver esos errores, de inmediato. Los backends que se saltan el último paso acumulan tablas de tokens en descomposición que desperdician envíos, distorsionan las métricas de entrega y frenan campañas — el problema del token viejo es aburrido, acumulativo y el bug de push más común del mundo real.
APNs vs. FCM
| APNs | FCM | |
|---|---|---|
| Alcanza | Dispositivos iOS — el único camino | Android de forma nativa; dispositivos iOS vía proxy hacia APNs |
| Auth | Clave de firma .p8 (key ID + team ID) | Credenciales de servidor desde la consola de la plataforma |
| Payload | ~4 KB · diccionario aps | ~4 KB · mensajes de notification + data |
| Manejo offline | Fusiona — conserva el más reciente por app | Encola con un TTL, hasta ~4 semanas |
| Prioridad | 10 (inmediata) vs. 5 (amigable con la batería) | High vs. normal |
| Extras | Collapse IDs, pushes en segundo plano | Topics, grupos de dispositivos, collapse keys |
La consecuencia práctica de la primera fila: todo backend cross-platform o integra ambos servicios, o usa FCM como superficie única (cargándole las credenciales de APNs), o le entrega el problema completo a una plataforma que guarda ambos juegos de credenciales — que es donde aterriza la sección de BaaS.
Lo que el push no promete
El contrato honesto, reunido en un solo lugar. Un 200 del servicio de push significa aceptado para entrega, no entregado. Los dispositivos offline no acumulan una cola fiel: APNs conserva solo la notificación más reciente por app; la cola de FCM expira con un TTL. Los optimizadores de batería en Android difieren la entrega de formas que no controlas; los usuarios pueden silenciar un canal o la app entera a nivel del SO, de forma invisible para tu backend. Los pushes silenciosos — despertares en segundo plano sin alerta visible — corren con un presupuesto horario mínimo y se descartan sin error al excederlo, según la documentación oficial de APNs; son pistas de refresh, no un protocolo de sincronización. La regla de diseño que se desprende: el push es el toque en el hombro — los datos en sí viajan por tu API cuando la app se abre, y cualquier cosa que deba llegar sí o sí gana un segundo canal.
Web push, en breve
Los navegadores estandarizaron su propia cadena: la página se suscribe vía la Push API usando tu par de claves VAPID (RFC 8292 — el servidor se identifica con un token firmado, sin registro ante ningún proveedor), el servicio de push del navegador devuelve una subscription (URL de endpoint + claves de cifrado) y tu servidor hace POST de payloads cifrados a ese endpoint según el Web Push Protocol. Un service worker recibe el evento push y muestra la notificación — con el sitio cerrado, y quizá el navegador cerrado en desktop. Cada fabricante de navegador opera su propio servicio de push; la URL del endpoint le dice a tu servidor dónde hacer el POST. La salvedad honesta: en iOS, el web push solo funciona para web apps instaladas en la pantalla de inicio.
Push vs. WebSockets vs. live queries
| Notificaciones push | WebSockets / live queries | |
|---|---|---|
| Estado de la app | Cerrada o en segundo plano | Abierta, conectada |
| Dirección | Un sentido, servidor → dispositivo | Full duplex / push por suscripción |
| Latencia y confiabilidad | Del orden de segundos, best-effort | Milisegundos, garantizada por la conexión |
| Payload | Resumen de ~4 KB + deep link | Lo que tu protocolo transporte |
| El híbrido | El patrón de producción: entrega por el socket si hay conexión; recurre al push tras unos segundos si no |
Son complementos con una frontera: el socket sirve al usuario que mira la pantalla; el push alcanza al usuario que dejó el teléfono. Las apps de chat demuestran el híbrido a diario — los mensajes fluyen por la conexión mientras la app está abierta, y el mismo mensaje se convierte en push en el momento en que deja de estarlo.
Casos de uso comunes
- Mensajes y menciones — el push canónico: alguien te necesita, la app está cerrada.
- Alertas transaccionales — pedido enviado, viaje llegando, pago acreditado: resúmenes de una línea con deep link hacia la app.
- Disparadores sensibles al tiempo — cambios de marcador, alertas de precio, momentos “X está en vivo” adyacentes a la presencia.
- Re-engagement — usado con moderación, con opt-outs por canal, o los usuarios lo desactivan todo.
- Pistas de badge y estado — el presupuesto silencioso gastado en empujar a la app a refrescarse antes de que el usuario la abra.
¿Deberías hacer push? Matriz de decisión
| Situación | Elige |
|---|---|
| El usuario debe enterarse aunque la app esté cerrada | Push — su trabajo definitorio |
| La app está abierta en pantalla | Live queries / sockets — más rápido, confiable |
| Los datos deben llegar, garantizado | Tu API + sincronización en segundo plano; el push como el toque |
| Audiencia web | Web push vía VAPID + service worker |
| Sincronizaciones silenciosas frecuentes | No lo hagas — el presupuesto las descartará; sincroniza al abrir |
| Ambas plataformas, un solo equipo | Una API sobre ambos servicios — el modo proxy de FCM o un BaaS |
Limitaciones y trade-offs
- La entrega es una probabilidad, no una promesa. Diseña flujos que sobrevivan a un push perdido; reconcilia al abrir la app.
- Los permisos son capital de un solo disparo. El prompt del SO (explícito en iOS y la web, en runtime en el Android moderno) convierte mejor pedido en contexto — y un prompt negado es casi irreversible.
- El registro de tokens es un dataset vivo. Sincroniza al arrancar, poda ante errores, o mira cómo la entregabilidad decae en silencio.
- Los payloads son semipúblicos. Las notificaciones se muestran en pantallas de bloqueo y viajan por infraestructura de terceros — resúmenes e IDs, nunca secretos.
- Dos sistemas de credenciales, una funcionalidad. Claves
.p8, credenciales de consola, expiración y rotación — el dolor de configuración es real, una vez por plataforma, y exactamente lo que las capas gestionadas absorben.
Push en Back4app
Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. El servicio de push de Back4app convierte toda la cadena en datos: cada instalación se registra como un objeto Installation — token de dispositivo, plataforma, canales y un puntero al usuario capturados automáticamente, como muestran las pestañas de cliente — y una sola llamada de envío direcciona canales (al estilo de topics) o cualquier consulta de Installations (“todos en scores en Android que no abrieron la app esta semana”), con la plataforma guardando tus credenciales de APNs y FCM y enrutando por dispositivo. Los envíos se disparan desde Cloud Code — un afterSave en Message haciendo push al destinatario es la mitad de fallback del patrón híbrido —, desde jobs programados o desde la consola del dashboard para campañas puntuales. La higiene de tokens, las credenciales duales y las rarezas de payload por plataforma se vuelven comportamiento de la plataforma; tu código decide quién y qué, no cómo.
Preguntas frecuentes
¿Qué es una notificación push?
Un mensaje iniciado en el servidor que el servicio de push del sistema operativo entrega al dispositivo y muestra incluso cuando la app no está corriendo. Esa última propiedad es la que la define — separa el push de los mensajes in-app, que necesitan la app abierta, y de los sockets, que necesitan una conexión viva.
¿Cómo funcionan las notificaciones push de punta a punta?
La app se registra con el servicio de push de su plataforma y recibe un token de dispositivo; la app le entrega ese token a tu backend; tu backend envía un payload más el token a APNs o FCM; el servicio de push lo entrega por la conexión persistente que el sistema operativo mantiene; el SO lo muestra o despierta la app.
¿Qué es un token de dispositivo?
Un identificador opaco de una instalación de la app en un dispositivo, emitido por el servicio de push de la plataforma — una dirección, no un secreto. Cambia con reinstalaciones, restauraciones o limpiezas de datos, y por eso las apps lo resincronizan con el backend en cada arranque y los backends lo borran cuando los envíos reportan que ya no existe.
¿Cuál es la diferencia entre APNs y FCM?
APNs es el único camino hacia los dispositivos iOS. FCM es el servicio de push de la plataforma Android — y funciona además como capa cross-platform: con las credenciales de APNs cargadas, acepta una solicitud y reemite una solicitud compatible con APNs para los dispositivos iOS. Una sola API, ambas plataformas.
¿Por qué mi servidor no puede hacer push directo a un dispositivo?
Porque solo el sistema operativo sostiene la única conexión persistente, optimizada para batería, con su servicio de push — un socket compartido por todas las apps del teléfono. Los servidores arbitrarios no pueden mantener conexiones abiertas a través de radios, NAT y estados de suspensión, así que todos los pushes se enrutan por los gateways de la plataforma.
¿Cómo funciona el web push?
A través de service workers: la página se suscribe con tu clave pública VAPID, el servicio de push del navegador devuelve una subscription — una URL de endpoint más claves de cifrado — y tu servidor hace POST de payloads cifrados a ese endpoint según el Web Push Protocol. El evento push del service worker muestra la notificación, incluso con el sitio cerrado.
¿La entrega del push está garantizada?
No — una respuesta de éxito de APNs o FCM significa aceptado, no entregado. Los dispositivos offline reciben colas fusionadas o con límite de tiempo, los optimizadores de batería retrasan la entrega y los usuarios pueden desactivar las notificaciones por completo. El push es best-effort por diseño; cualquier cosa crítica necesita además otro canal.
¿Qué son las notificaciones push silenciosas?
Pushes en segundo plano que despiertan la app para traer datos sin mostrar una alerta. Están fuertemente limitados — piensa en un pequeño presupuesto por hora, con los envíos que lo exceden descartados sin error — así que funcionan como pistas de refresh, nunca como un transporte de sincronización confiable.