18 dic 2025·7 min de lectura

APNs vs FCM para notificaciones push en iOS y Android

Comparativa APNs vs FCM para iOS y Android: ciclo de vida de tokens, límites de payload, expectativas de entrega y una lista práctica para arreglar notificaciones que no llegan.

APNs vs FCM para notificaciones push en iOS y Android

Qué estás comparando (y por qué importa)

APNs (Apple Push Notification service) y FCM (Firebase Cloud Messaging) son las tuberías que trasladan un mensaje desde tu servidor hasta un teléfono. No deciden qué hace tu app con el mensaje, pero influyen mucho en si llega, con qué rapidez llega y en qué formato debe venir.

Cuando la gente dice que una notificación “funciona en Android pero no en iOS” (o al revés), rara vez hay un solo fallo. iOS y Android manejan el trabajo en segundo plano, el ahorro de energía, los permisos y la prioridad del mensaje de forma diferente. El mismo mensaje puede retrasarse, ser reemplazado por uno más nuevo, mostrarse sin sonido o no mostrarse nunca si la app no puede despertarse para procesarlo.

Esta comparación se centra en las partes que más sorprenden en la práctica: cómo cambian los tokens de dispositivo con el tiempo, cuánto puedes incluir en el payload y cómo debe estructurarse, qué entrega puedes esperar razonablemente y las causas habituales por las que las notificaciones parecen desaparecer.

No cubre la elección de una UI de proveedor de push, estrategias de marketing ni construir una canalización completa de analítica. El objetivo aquí es la fiabilidad y depurar más rápido.

Algunos términos usados a lo largo del texto:

  • Token: una dirección específica de dispositivo a la que envías, emitida por APNs o FCM.
  • Topic: una dirección de grupo (usada principalmente con FCM) a la que se suscriben muchos dispositivos.
  • Canal: una categoría de notificación en Android que controla sonido, importancia y comportamiento.
  • Collapse key: una forma de reemplazar mensajes pendientes antiguos por uno nuevo.
  • TTL (time to live): cuánto tiempo puede esperar un mensaje antes de expirar.

Hacer bien estas bases ahorra horas de adivinanza cuando un “push simple” se comporta distinto entre iOS y Android.

Cómo funcionan APNs y FCM a alto nivel

APNs y FCM son intermediarios entre tu servidor y el teléfono del usuario. Tu app no puede entregar una notificación de forma fiable directamente al dispositivo por internet, así que delega ese trabajo a Apple (APNs) o Google (FCM), que mantienen conexiones de confianza con sus dispositivos.

El flujo general es similar: tu app obtiene un token, tu backend envía un mensaje al servicio de push usando ese token y el servicio lo enruta al dispositivo.

APNs en términos sencillos

En iOS, la app se registra para notificaciones remotas y (habitualmente) pide permiso al usuario. Apple entonces proporciona un token de dispositivo. Tu backend (a menudo llamado “provider”) envía una petición de push a APNs que incluye ese token y tu payload. APNs decide si puede entregar y reenvía la notificación al dispositivo.

Tu backend se autentica en APNs, normalmente usando autenticación basada en token (una clave de firma). Configuraciones antiguas usan certificados.

FCM en términos sencillos

En Android, la instancia de la app se registra con FCM y recibe un token de registro. Tu backend envía un mensaje a FCM, y FCM lo enruta al dispositivo correcto. Dependiendo del estado de la app y del tipo de mensaje, FCM puede mostrar la notificación automáticamente o entregar datos a la app para que los maneje.

Tu backend se autentica en FCM usando credenciales de servidor (API key o cuenta de servicio).

Lo que controlas: el código de la app, cuándo pides permiso, el almacenamiento de tokens, la lógica del backend y el payload que envías. Lo que controlan Apple y Google: la red de entrega, la alcanzabilidad, reglas de throttling y muchas condiciones de última milla como ahorro de energía y políticas del sistema.

Ciclo de vida del token: cómo se emiten, actualizan y anulan

La mayor diferencia diaria entre APNs y FCM es que los tokens no son “fijos para siempre”. Trátalos como direcciones que pueden cambiar sin avisar.

En iOS, el token de dispositivo de APNs está ligado al dispositivo, tu app y tu configuración de desarrollador de Apple. Puede cambiar tras reinstalar la app, restaurar el dispositivo, ciertas actualizaciones del OS o al cambiar entornos de push (sandbox vs producción) durante el desarrollo.

En Android, el token de registro de FCM puede renovarse cuando la app se restaura en un dispositivo nuevo, el usuario borra datos de la app, Google rota el token o la app se reinstala. Tu app debe esperar eventos de refresh y enviar el token nuevo al servidor con rapidez.

Una regla simple: siempre haz upsert de tokens, nunca “insertar y olvidar”. Cuando almacenes tokens, guarda suficiente contexto para evitar duplicados y objetivos erróneos:

  • ID de usuario o cuenta (si aplica)
  • Bundle/package de la app y entorno
  • Plataforma (iOS/Android)
  • Valor del token y marca temporal de última vez visto
  • Estado de opt-in (permiso concedido/denegado)

Las eliminaciones también importan. Normalmente sabes que un token está muerto por errores de entrega, no por una señal limpia de “desinstalación”. Si APNs devuelve un error como Unregistered (a menudo con código 410), o FCM responde NotRegistered/Unregistered, quita ese token inmediatamente para no seguir reintentando para siempre.

Una forma fácil de filtrar actualizaciones privadas: un cliente cierra sesión y otro inicia sesión en el mismo teléfono. Si no borras o reasignas el token al cerrar sesión, puedes enviar notificaciones a la persona equivocada aunque la entrega “funcione”.

Restricciones de payload y diferencias en la estructura de mensajes

La diferencia práctica más grande entre APNs y FCM es cuánto puedes meter en un mensaje y cómo el teléfono lo trata al llegar.

La mayoría de equipos usa un conjunto pequeño de campos:

  • Título y texto del cuerpo
  • Contador de badges (iOS)
  • Sonido (por defecto o personalizado)
  • Datos personalizados clave-valor (por ejemplo, order_id, status)

Límites de tamaño: mantén el push pequeño

Ambos servicios tienen límites de tamaño de payload, y el límite incluye tus datos personalizados. Cuando alcanzas el límite, la entrega puede fallar o el mensaje no se comportará como esperas.

Un patrón fiable es enviar una notificación corta más un ID, y luego obtener los detalles desde tu backend:

Ejemplo: en lugar de enviar un resumen completo del pedido, envía {"type": "order_update", "order_id": "123"} y deja que la app llame a tu API para cargar el estado más reciente.

Comportamiento de “data-only” vs notificación

En Android, un mensaje FCM con un payload de “notification” suele ser mostrado por el sistema cuando la app está en background. Un mensaje solo de datos se entrega al código de tu app, pero puede retrasarse o bloquearse por límites en segundo plano y ajustes de batería.

En iOS, las alertas (título/cuerpo) son directas, pero las actualizaciones en background son más estrictas. Un push en background no garantiza que tu código se ejecute inmediatamente. Trátalo como una sugerencia para actualizar, no como un disparador en tiempo real.

Si necesitas fiabilidad, mantén el payload mínimo, incluye un identificador estable y diseña la app para reconciliar el estado cuando se abra o reanude.

Expectativas de entrega y qué puede impedir una notificación

Estandariza tu runbook de push
Convierte tu lista de comprobación de resolución de problemas en flujos backend repetibles que tu equipo pueda confiar.
Comenzar gratis

Con APNs y FCM la entrega es best-effort. El proveedor intentará entregar tu mensaje, pero no promete que el dispositivo lo muestre.

La alcanzabilidad es el primer limitador. Envías una notificación con un time-to-live (TTL) o fecha de expiración. Si el dispositivo vuelve a conexión después de esa ventana, el push se descarta. Si el TTL es muy largo, el usuario podría ver una alerta antigua más tarde, lo que parece un bug.

La prioridad afecta el tiempo, pero no es una mejora gratuita. Alta prioridad puede ayudar a que mensajes sensibles al tiempo lleguen antes, especialmente si el dispositivo está dormido. Abusar de ella puede provocar throttling, desgaste de batería o que el SO considere tu app ruidosa.

Ambos sistemas soportan colapso para que un mensaje nuevo reemplace a uno antiguo en lugar de acumularse. APNs usa un identificador de colapso y FCM usa collapse key. Si colapsas en algo como order_status, el usuario podría ver solo el estado más reciente, no cada paso.

Incluso cuando el proveedor entrega correctamente, el teléfono todavía puede evitar que el usuario lo vea:

  • Modos No molestar o Focus pueden silenciar u ocultar alertas
  • Ajustes de notificaciones de la app pueden estar desactivados o en entrega silenciosa
  • Los canales de notificación de Android pueden estar apagados para una categoría específica
  • Restricciones en segundo plano o ahorradores de batería pueden retrasar la entrega
  • El SO puede suprimir repetidos si tu app publica muchas alertas similares

Trata el push como un transporte poco fiable: guarda el estado importante en tu backend y haz que la app refresque el estado actual al abrirla, incluso si una notificación nunca se muestra.

Permisos y ajustes del dispositivo que afectan la entrega

Muchos “problemas de entrega” son en realidad cuestiones de permisos y ajustes.

En iOS, el primer cuadro de permiso importa. Si el usuario pulsa “No permitir”, las notificaciones no aparecerán hasta que lo cambie en Ajustes. Incluso tras permitirlas, pueden desactivar Pantalla bloqueada, Centro de notificaciones, banners, sonidos o badges. Los modos Focus y el Resumen programado también pueden ocultar o retrasar alertas.

En Android, los requisitos dependen de la versión del SO. Versiones más nuevas requieren un permiso de notificaciones en tiempo de ejecución, así que una actualización de la app puede dejar de mostrar notificaciones hasta que el usuario lo apruebe de nuevo. La visibilidad también depende de los canales de notificación. Si el canal está silenciado o en baja importancia, los pushes pueden llegar pero no interrumpir.

Las restricciones en segundo plano también pueden romper expectativas. Modo de bajo consumo en iOS y optimizaciones de batería en Android pueden retrasar trabajo en background, impedir datos en segundo plano o evitar que la app procese un mensaje solo de datos.

Para confirmar qué está pasando, registra lo que el dispositivo ve, no solo lo que envía tu backend:

  • Registros en la app: “permiso concedido”, “token registrado”, “notificación recibida”, “notificación mostrada”
  • Indicadores del SO: estado de los ajustes de notificación (habilitado/silenciado/importancia del canal) y modo de batería
  • Callbacks de push: si tu app recibió el mensaje en primer plano/segundo plano

Aunque tu backend esté construido en una herramienta no-code, los registros del cliente siguen siendo lo que separa “mensaje no recibido” de “recibido pero suprimido”.

Paso a paso: cómo depurar notificaciones que faltan

Centraliza la higiene de tokens push
Modela el almacenamiento de tokens, los registros y las reglas de envío en un solo lugar para poder depurar más rápido.
Probar AppMaster

Cuando falta un push, trátalo como una cadena: token, proveedor, payload y comportamiento de la app. Los síntomas pueden parecer iguales en iOS y Android, así que revisa estos puntos en orden.

  • Confirma que estás enviando a un token actual. Compara el token almacenado en tu servidor con el que la app informó más recientemente. Registra cuándo recibiste cada token por última vez.
  • Valida el payload antes de enviarlo. Manténlo dentro de los límites de la plataforma, usa campos requeridos y evita JSON malformado. Si envías mensajes solo de datos, confirma que la app está preparada para manejarlos.
  • Revisa las credenciales y el entorno del proveedor. Para APNs, confirma clave/certificado, team, bundle ID y si apuntas a sandbox o producción. Para FCM, confirma las credenciales del proyecto correcto.

Luego reduce si el problema es el contenido del mensaje o el comportamiento del dispositivo/app:

  • Envía una notificación de prueba mínima. Un payload pequeño con título/cuerpo ayuda a confirmar que el transporte funciona.
  • Verifica handlers en la app y comportamiento en primer plano. Muchas notificaciones “faltantes” se reciben pero no se muestran. Algunas apps suprimen banners en primer plano a propósito.
  • Cambia una variable a la vez. Prueba otro dispositivo, una versión distinta del SO, Wi‑Fi vs datos móviles y otra cuenta de usuario. Si solo falla una cuenta, suele apuntar a tokens obsoletos o a segmentación en el servidor.

Un patrón práctico: si usuarios iOS reportan ausencias pero Android está bien, empieza enviando una alerta mínima en iOS. Si eso funciona, céntrate en la estructura del payload y el manejo en la app. Si no funciona, revisa tokens y credenciales/entorno de APNs.

Errores comunes que provocan fallos silenciosos

Construye un backend seguro para tokens
Crea un backend que haga *upsert* de tokens, registre la última vez visto y evite objetivos duplicados.
Comenzar a construir

La mayoría de problemas de push no son caídas del servicio. Son pequeñas discrepancias entre lo que tu app espera y lo que APNs o FCM aceptan, o lo que el teléfono permite.

El más común es enviar a un token que ya no es válido. Los tokens cambian tras reinstalar, restaurar o renovarse. Si tu servidor sigue usando el valor antiguo, los pushes no llegan a ningún lado.

Otro error es tratar la entrega push como garantizada. La entrega best-effort implica mensajes tardíos o faltantes cuando los dispositivos están offline o bajo reglas de ahorro de energía. Para eventos importantes (actualizaciones de pedido, alertas de seguridad) necesitas una alternativa dentro de la app, como obtener el estado al abrirla.

Causas frecuentes de notificaciones faltantes:

  • Tokens obsoletos de iOS o Android guardados tras reinstalación/renovación
  • Exceder límites de payload (demasiados datos personalizados, imágenes grandes, cadenas largas)
  • Confiar en entrega en background para actualizaciones silenciosas y acabar siendo throttled por límites del SO
  • Mezclar entornos iOS (desarrollo vs producción), de modo que token y endpoint de APNs no coinciden
  • Ignorar la desactivación por parte del usuario, Focus/Do Not Disturb, canales desactivados (Android) o permisos de la app

Ejemplo: una app de retail envía una alerta “pedido enviado” con un JSON grande del historial de seguimiento. La llamada de envío parece correcta, pero el payload es rechazado o truncado y el usuario no ve nada. Mantén el push pequeño y deja los detalles detrás de una llamada a la API.

Lista rápida antes de culpar a APNs o FCM

Antes de asumir que el proveedor es el problema, haz una comprobación rápida:

  • Confirma que el token es correcto para el usuario y el dispositivo. Debe existir, actualizarse recientemente y mapearse a la sesión correcta.
  • Verifica que las credenciales del proveedor son válidas ahora mismo. Revisa claves/certs de APNs y que las credenciales de FCM coincidan con la app/proyecto correcto.
  • Valida forma y tamaño del payload. Mantente dentro de límites y usa campos correctos.
  • Configura TTL, prioridad y colapso a propósito. Un TTL bajo puede expirar antes de que el teléfono se conecte. Baja prioridad puede retrasar la entrega. El colapso puede reemplazar mensajes anteriores.
  • Separa “aceptado por el servidor” de “mostrado en el dispositivo”. Compara logs del servidor (request/response/ID de mensaje) con logs del cliente (token usado, handler llamado).

Luego haz una comprobación rápida en el dispositivo: notificaciones permitidas para la app, canal/categoría correcto (los canales de Android son un fallo común), modos Focus/No molestar y restricciones en segundo plano.

Ejemplo: diagnosticar una notificación de actualización de pedido que falta

Genera apps nativas para ambas plataformas
Publica apps nativas para iOS y Android que funcionen con APNs y FCM de la forma correcta.
Construir apps móviles

Un agente de soporte pulsa “Enviar actualización de pedido” para el pedido #1842. Los logs del backend muestran “notificación enviada”, pero el cliente no ve nada en su iPhone ni en su Android.

Empieza por el backend. La mayoría de notificaciones “faltantes” o no son aceptadas por el servicio de push o son aceptadas y luego descartadas porque el dispositivo no puede (o no quiere) mostrarlas.

Comprobaciones en el backend

Busca un intento de envío único y trazable (una actualización de pedido debería producir una petición de push). Luego verifica:

  • El token usado es el token más reciente almacenado para ese usuario y dispositivo.
  • La respuesta del proveedor es un éxito y guardaste cualquier código de error.
  • El payload respeta las reglas de la plataforma (límites de tamaño, campos requeridos, JSON válido).
  • La autenticación es válida (clave/cert de APNs y team/bundle IDs, o credenciales de FCM).
  • Apuntas al entorno iOS correcto (sandbox vs producción).

Si tus logs muestran rechazo como “unregistered/invalid token”, es un problema del ciclo de vida del token. Si el proveedor acepta el mensaje pero no llega nada, céntrate en el tipo de payload y el comportamiento del SO.

Comprobaciones en el teléfono

Ahora valida que el teléfono pueda mostrar la alerta:

  • Las notificaciones están habilitadas para la app (y permitidas en Pantalla bloqueada/Banners).
  • Focus/Do Not Disturb o resúmenes programados no la están ocultando.
  • Modos de ahorro de batería no están restringiendo el trabajo en background (más común en Android).
  • El estado de la app coincide con el tipo de mensaje (el manejo en primer plano puede tragarse las alertas).

Un resultado común: el token está bien, pero el mensaje es solo de datos (Android) o falta la configuración de iOS para manejo en background, así que el SO no muestra una alerta. La solución es enviar el tipo de payload correcto según lo que quieras (alerta visible vs actualización en background) y mantener registros limpios de actualizaciones de token y respuestas del proveedor.

Próximos pasos: hacer el push más fiable en tu producto

Las notificaciones push parecen sencillas hasta que se convierten en una función central. La fiabilidad viene de las piezas que controlas: higiene de tokens, disciplina del payload y una vía de recuperación.

Planifica fallos. El push es perfecto para momentos de “mirar ahora”, pero no debe ser la única ruta para eventos críticos. Una bandeja en la app ayuda a que los usuarios se pongan al día más tarde, y el correo o SMS pueden cubrir acciones de alto valor como restablecer contraseña o problemas de pago.

Mantén el payload ligero. Trata la carga push como un aviso, no como el mensaje completo. Envía un tipo de evento y un ID, y luego obtén los detalles desde tu API cuando la app se abra o reciba una actualización en background adecuada.

Escribe un runbook corto para tu equipo para que la depuración sea consistente: estado de opt-in, frescura de tokens, códigos de respuesta del proveedor, tamaño/forma del payload y entorno/credenciales.

Si construyes con AppMaster (appmaster.io), puede ser cómodo mantener el almacenamiento de tokens, los registros de auditoría y la lógica que dispara los envíos en un solo backend, mientras sigues entregando apps nativas iOS y Android que manejan APNs y FCM correctamente.

FAQ

¿Cuál es la forma más simple de explicar APNs vs FCM?

APNs es el servicio de entrega de Apple para notificaciones push en iOS, y FCM es el servicio de entrega de Google para Android (y también puede dirigirse a iOS vía APNs). Tu app sigue decidiendo qué hacer con el mensaje, pero estos servicios determinan cómo te autenticas, cómo formateas las cargas y qué comportamiento de entrega puedes esperar.

¿Los tokens de dispositivo permanecen iguales para siempre?

Trata los tokens como direcciones que pueden cambiar. Almacénalos con detalles de plataforma y entorno, actualízalos siempre que la app reporte un valor nuevo y elimínalos cuando el proveedor te diga que son inválidos. La regla práctica es upsert de tokens y mantener una marca de tiempo “última vez visto” para detectar registros obsoletos rápidamente.

¿Qué suele causar que un token de push cambie?

En iOS, los tokens suelen cambiar tras reinstalar la app, restaurar el dispositivo, algunas actualizaciones del sistema o al cambiar entre sandbox y producción en desarrollo. En Android, los tokens de FCM pueden renovarse tras reinstalar, al borrar datos de la app, al restaurar el dispositivo o cuando Google rota los tokens. La app debe escuchar eventos de renovación y enviar el token nuevo al backend de inmediato.

¿Cómo debo estructurar una carga push para evitar problemas?

Mantén la carga de la notificación pequeña y trátala como un aviso. Envía un título/cuerpo corto (si quieres una alerta visible) más un identificador estable como order_id, y deja que la app recupere los detalles completos desde tu API. Esto evita límites de payload, reduce casos extraños y hace el comportamiento más consistente entre plataformas.

¿Cuál es la diferencia entre mensajes “notification” y “data-only”?

Una carga de tipo "notification" está pensada para mostrarse al usuario, mientras que una "data-only" está pensada para que la app la procese. En Android, los mensajes data-only pueden retrasarse o bloquearse por límites de background y ajustes de batería, por lo que no son fiables como desencadenante inmediato. En iOS, los pushes en background tampoco garantizan que tu código se ejecute de inmediato; son más bien una sugerencia para actualizar.

¿Las notificaciones push están garantizadas para ser entregadas y mostradas?

No. La entrega es "best-effort". Aunque APNs o FCM acepten tu solicitud, el dispositivo puede estar desconectado, el mensaje puede expirar por TTL, el sistema puede aplicar throttling o la configuración del usuario puede suprimir la alerta. Diseña tu app para que el estado crítico esté correcto cuando el usuario la abra, aunque la notificación no se muestre.

¿Cuál es la forma más rápida de depurar una notificación que no llega?

Empieza separando “enviado” de “mostrado”. Confirma que el token está actualizado, envía una carga de prueba mínima con título/cuerpo y verifica que usas las credenciales de APNs/FCM correctas y (en iOS) el entorno adecuado. Si el proveedor acepta el mensaje, revisa los ajustes del teléfono como Focus/No molestar, permisos de notificación de la app y canales de Android, porque la notificación puede recibirse pero quedarse suprimida.

¿Por qué las notificaciones funcionan en Android pero no en iOS (o al revés)?

En iOS, muchos problemas vienen de la denegación de permisos, modos Focus o apuntar al entorno APNs equivocado (sandbox vs producción). En Android, los bloqueos comunes son el permiso de notificaciones en tiempo de ejecución en versiones nuevas, canales de notificación silenciados/baja importancia y optimizaciones de batería agresivas que retrasan el procesamiento en background. Un mismo envío desde el backend puede parecer correcto mientras el dispositivo impide que el usuario vea la alerta.

¿Cómo afectan el TTL y la “collapse key” lo que los usuarios ven?

TTL controla cuánto tiempo debe intentar el proveedor reenviar mientras el dispositivo esté desconectado, y la configuración de colapso decide si un mensaje nuevo reemplaza a uno anterior pendiente. Un TTL corto puede hacer que la notificación desaparezca si el teléfono está offline, y las claves de colapso pueden hacer que solo se vea la actualización más reciente. Ajusta estos valores intencionalmente según la experiencia que quieras ofrecer.

¿Cómo puede AppMaster ayudarme a construir una configuración de push fiable?

Centraliza el almacenamiento de tokens, las reglas de segmentación y los registros de envío para que puedas rastrear cada intento de push de extremo a extremo. AppMaster (appmaster.io) puede ayudar centralizando tablas de tokens, auditoría y la lógica que dispara los envíos en un único backend, mientras tus apps nativas manejan APNs y FCM correctamente. La clave es registrar actualizaciones de tokens, respuestas del proveedor y la recepción en el cliente para identificar si la falla está en el servidor, el proveedor o el dispositivo.

Fácil de empezar
Crea algo sorprendente

Experimente con AppMaster con plan gratuito.
Cuando esté listo, puede elegir la suscripción adecuada.

Empieza