---
term: 'Notificaciones Push (APNs y FCM)'
seoTitle: 'Notificaciones push: APNs, FCM, tokens de dispositivo y Web Push'
headline: '¿Qué son las Notificaciones Push (APNs y FCM)?'
slug: notificaciones-push
category: backend-compute
shortDefinition: '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.'
relatedTerms:
  - websockets-real-time-sync
  - real-time-live-queries
  - background-jobs-task-schedulers
  - presence-online-status
contrastsWith:
  - websockets-real-time-sync
aboutTerms:
  - 'Token de dispositivo'
  - 'APNs'
  - 'FCM'
  - 'Web Push (VAPID)'
faq:
  - question: '¿Qué es una notificación push?'
    answer: '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.'
  - question: '¿Cómo funcionan las notificaciones push de punta a punta?'
    answer: '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.'
  - question: '¿Qué es un token de dispositivo?'
    answer: '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.'
  - question: '¿Cuál es la diferencia entre APNs y FCM?'
    answer: '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.'
  - question: '¿Por qué mi servidor no puede hacer push directo a un dispositivo?'
    answer: '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.'
  - question: '¿Cómo funciona el web push?'
    answer: '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.'
  - question: '¿La entrega del push está garantizada?'
    answer: '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.'
  - question: '¿Qué son las notificaciones push silenciosas?'
    answer: '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.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Apple — Sending notification requests to APNs'
    url: 'https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns'
  - name: 'RFC 8030 — Generic Event Delivery Using HTTP Push'
    url: 'https://datatracker.ietf.org/doc/html/rfc8030'
  - name: 'RFC 8292 — VAPID for Web Push'
    url: 'https://datatracker.ietf.org/doc/html/rfc8292'
  - name: 'W3C Push API'
    url: 'https://www.w3.org/TR/push-api/'
cta:
  title: 'Una API de push para cada dispositivo'
  text: 'El servicio de push de Back4app guarda tus credenciales de APNs y FCM una sola vez, registra cada instalación como un objeto Installation y envía por canal o por consulta — desde Cloud Code, el SDK o el dashboard.'
  linkText: 'Empieza gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-08-31'
translationKey: push-notifications-apns-fcm
---

**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](/glossary/es/websockets/) sirven a las *abiertas* |

## La cadena de entrega, de punta a punta

```text
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:**

```javascript
// 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
// 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.
```

**Swift:**

```swift
// 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.
```

**Kotlin:**

```kotlin
// 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.
```

```mermaid
flowchart LR
  accTitle: Entrega de notificaciones push a través de los servicios de push de la plataforma
  accDescr: La app se registra con el servicio de push de su plataforma y recibe un token de dispositivo, que sincroniza con el backend de la aplicación. El backend envía payloads con tokens a APNs o FCM, que entregan por la única conexión persistente que cada sistema operativo mantiene, y el SO muestra la notificación incluso cuando la app está cerrada.
  A["App en el dispositivo"] -->|"1 · registro"| PS["Servicio de push de la plataforma<br/>APNs / FCM"]
  PS -->|"2 · token de dispositivo"| A
  A -->|"3 · sincroniza el token"| B["Tu backend<br/>registro de tokens"]
  B -->|"4 · payload + token"| PS
  PS -->|"5 · una conexión persistente<br/>del SO"| OS["SO del dispositivo"]
  OS -->|"6 · muestra / despierta la app"| N["Notificación<br/>(la app puede estar cerrada)"]
```

## 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](https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-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](https://www.w3.org/TR/push-api/) usando tu par de claves **VAPID** ([RFC 8292](https://datatracker.ietf.org/doc/html/rfc8292) — 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](https://datatracker.ietf.org/doc/html/rfc8030). 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](/glossary/es/websockets/) / [live queries](/glossary/es/live-queries-tiempo-real/) |
| --- | --- | --- |
| 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](/glossary/presence-online-status/).
- **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](/glossary/es/live-queries-tiempo-real/) — más rápido, confiable |
| Los datos deben llegar, garantizado | Tu API + [sincronización en segundo plano](/glossary/background-jobs-task-schedulers/); 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](/glossary/es/cloud-code-funciones-serverless/) — un `afterSave` en `Message` haciendo push al destinatario es la mitad de fallback del patrón híbrido —, desde [jobs](/glossary/background-jobs-task-schedulers/) 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.
