Cómo ser compatible con el envío directo mediante tokens de FCM/APNs

Escenarios aplicables

Este artículo es para usted si su app cumple lo siguiente:

  • La app ya se conecta directamente a Google FCM y a iOS APNs, posee sus propios tokens de FCM y de APNs, y envía notificaciones de forma autónoma con los protocolos nativos;
  • Las versiones históricas de la app no integraron el SDK de EngageLab AppPush, por lo que una gran cantidad de usuarios existentes no tiene un registration_id de EngageLab y no puede alcanzarse mediante la API de creación de envíos;
  • Desea incorporar primero a estos usuarios existentes al sistema de envío de EngageLab sin forzar la actualización de la app, y luego migrar gradualmente al SDK.

Descripción general de la solución

Para este escenario, EngageLab ofrece la API de registro de dispositivos: su servidor envía directamente los tokens de FCM o los device tokens de APNs que ya posee, y EngageLab genera para cada uno un registration_id asociado de forma única. A partir de ahí, puede enviar mensajes por registration_id mediante la API de creación de envíos, igual que con los usuarios registrados por SDK, y utilizar capacidades basadas en registration_id como etiquetas, alias y estadísticas.

flowchart LR
    token["Tokens FCM / APNs<br/>que usted ya posee"]
    register["API de registro de dispositivos<br/>/v4/devices/token/registration_id"]
    regId["registration_id"]
    push["API de creación de envíos<br/>/v4/push"]
    device["El dispositivo del usuario<br/>recibe la notificación"]

    token --> register --> regId --> push --> device

Pasos de integración:

  1. Su servidor llama a la API de registro de dispositivos para enviar tokens por lotes según la plataforma (de 1 a 500 por solicitud) y guarda la correspondencia entre el registration_id devuelto y cada token;
  2. Al enviar, indique el registration_id de los usuarios objetivo en to.registration_id de la API de creación de envíos;
  3. Cuando un token cambie (onNewToken de FCM, nuevo registro en APNs), vuelva a llamar a la API de registro de dispositivos para obtener el nuevo registration_id.

Una pregunta frecuente tras la integración es: cuando el usuario pulsa la notificación en su teléfono, ¿la app abre la página de inicio o puede ir directamente a una página de destino como el detalle de un pedido? A continuación se explica tomando como ejemplo FCM en Android.

La parte sobre "navegación al pulsar la notificación" que sigue solo cubre el escenario de notificaciones nativas de FCM en Android. La navegación al pulsar en iOS (registro con token de APNs) queda fuera del alcance de este artículo.

Es posible abrir una página de destino, pero no se obtiene automáticamente solo por haber registrado un registration_id.

  • De forma predeterminada, pulsar la notificación solo abre la app;
  • La página concreta a la que se accede la decide la lógica de gestión de clics de su propia app;
  • Para abrir una página de destino, el servidor debe indicar intent.url en la solicitud de envío y su app debe proporcionar una Activity capaz de responder a esa action.

La API de registro de dispositivos solo establece la correspondencia entre el token de FCM y el registration_id; no añade ninguna capacidad de navegación a su app, y estos usuarios tampoco pasan por la lógica de redirección de clics en notificaciones que depende del SDK de EngageLab. Por tanto, se trata de una solución de transición; a largo plazo seguimos recomendando migrar al SDK de EngageLab AppPush, como se detalla en la sección "Recomendación a largo plazo" al final.

Comportamiento predeterminado: sin acción de clic configurada

Cuando la solicitud de envío no configura notification.android.intent, la notificación que EngageLab entrega a FCM no incluye click_action. En ese caso, el comportamiento al pulsar sigue por completo el comportamiento predeterminado de FCM:

  • Si la app está en segundo plano o se ha cerrado, FCM muestra la notificación automáticamente y, al pulsarla, se abre la Activity de inicio de la app (la declarada como MAIN/LAUNCHER en AndroidManifest.xml);
  • Que el usuario final vea la página de inicio, la de inicio de sesión o la página en la que se encontraba antes depende de la lógica de arranque de su app y del estado actual de la pila de tareas.

Por tanto, "abrir la app de forma predeterminada" no equivale a "volver siempre a la página de inicio". Consulte la documentación oficial de Firebase: Recibir mensajes en una app de Android.

Abrir una página de destino: intent.url → click_action

Cadena de correspondencia

El servidor de EngageLab asigna el valor de notification.android.intent.url de la API de creación de envíos al campo android.notification.click_action de la notificación FCM; después, el sistema Android busca en su app una Activity que coincida con esa action.

flowchart LR
    pushApi["API de creación de envíos<br/>notification.android.intent.url"]
    fcm["Mensaje FCM<br/>android.notification.click_action"]
    activity["Su app<br/>Activity que coincide con la action"]
    target["Página de negocio de destino<br/>(p. ej., detalle del pedido)"]

    pushApi --> fcm --> activity --> target

La definición oficial de click_action está en FCM AndroidNotification.

Paso 1: el servidor indica intent.url en la solicitud de envío

Al enviar por registration_id, añada intent.url dentro de notification.android y transmita los parámetros de negocio mediante extras:

curl -X POST https://pushapi-sgp.engagelab.com/v4/push \ -u "appKey:masterSecret" \ -H "Content-Type: application/json" \ -d '{ "from": "push", "to": { "registration_id": ["13065ffa4e1a6cc91c3"] }, "body": { "platform": "android", "notification": { "android": { "title": "Pedido enviado", "alert": "Su pedido 20260911001 ha sido enviado. Pulse para ver el seguimiento", "intent": { "url": "intent:#Intent;action=com.example.app.ORDER_DETAIL;component=com.example.app/com.example.app.OrderDetailActivity;end" }, "extras": { "order_id": "20260911001", "page": "order_detail" } } } }, "request_id": "order-shipped-20260911001" }'
              
              curl -X POST https://pushapi-sgp.engagelab.com/v4/push \
  -u "appKey:masterSecret" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "push",
    "to": {
      "registration_id": ["13065ffa4e1a6cc91c3"]
    },
    "body": {
      "platform": "android",
      "notification": {
        "android": {
          "title": "Pedido enviado",
          "alert": "Su pedido 20260911001 ha sido enviado. Pulse para ver el seguimiento",
          "intent": {
            "url": "intent:#Intent;action=com.example.app.ORDER_DETAIL;component=com.example.app/com.example.app.OrderDetailActivity;end"
          },
          "extras": {
            "order_id": "20260911001",
            "page": "order_detail"
          }
        }
      }
    },
    "request_id": "order-shipped-20260911001"
  }'

            
Este bloque de código se muestra en una ventana flotante

Sobre el valor de intent.url, tenga en cuenta:

  • Utiliza el formato Intent URI de Android (intent:#Intent;...;end); no es una dirección web cualquiera;
  • action es el nombre de acción personalizado de su app y component es nombre del paquete/nombre completo de la clase Activity;
  • En una misma url puede indicarse solo action o solo component, pero se recomienda indicar ambos para acertar con precisión la Activity de destino;
  • Para más tipos de valores (abrir la página de inicio, Deeplink, etc.), consulte la descripción de intent en los campos de notificación de android de la API de creación de envíos.

Paso 2: su app proporciona una Activity que coincida

En AndroidManifest.xml, declare en la Activity de destino un intent-filter cuya action coincida con la de intent.url:

<activity android:name=".OrderDetailActivity" android:exported="true"> <intent-filter> <action android:name="com.example.app.ORDER_DETAIL" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
              
              <activity
    android:name=".OrderDetailActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="com.example.app.ORDER_DETAIL" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

            
Este bloque de código se muestra en una ventana flotante

Cuando FCM muestra la notificación y el usuario la pulsa, se inicia la Activity correspondiente con esa action y los pares clave-valor de extras de la notificación se colocan en los extras del Intent. La Activity de destino lee los parámetros y completa el enrutamiento de negocio:

class OrderDetailActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val orderId = intent.getStringExtra("order_id") if (orderId.isNullOrEmpty()) { // Si falta el parámetro, volver a la lista de pedidos o a la página de inicio startActivity(Intent(this, MainActivity::class.java)) finish() return } showOrderDetail(orderId) } }
              
              class OrderDetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val orderId = intent.getStringExtra("order_id")
        if (orderId.isNullOrEmpty()) {
            // Si falta el parámetro, volver a la lista de pedidos o a la página de inicio
            startActivity(Intent(this, MainActivity::class.java))
            finish()
            return
        }
        showOrderDetail(orderId)
    }
}

            
Este bloque de código se muestra en una ventana flotante

Si su app ya cuenta con una página de enrutamiento unificada (por ejemplo, todos los clics en notificaciones entran primero en PushRouterActivity, que luego distribuye a las páginas concretas según los parámetros), puede apuntar el component de intent.url a esa página intermedia; esta leerá los extras y navegará a la página de negocio, como el detalle del pedido, sin necesidad de declarar una action por cada página.

Consideraciones

  • ¿Es necesario integrar el SDK de EngageLab? No. La cadena anterior solo depende del mecanismo click_action de FCM y de las declaraciones de Activity de su propia app.
  • La gestión existente de click_action puede reutilizarse: si su app ya implementó la lógica de click_action cuando enviaba directamente con FCM, basta con indicar el valor de action original en intent.url.
  • Si no hay gestión de click_action, debe añadirse: si su app actualmente solo depende del comportamiento de apertura predeterminado, debe añadir la declaración de Activity y la lógica de análisis de parámetros según el "Paso 2"; de lo contrario, aunque el servidor configure intent.url, el sistema no encontrará ninguna Activity que pueda responder.
  • Los parámetros de negocio se transmiten mediante extras: intent.url decide "qué página abrir"; el contenido que se muestra en la página debe transmitirse mediante extras (como order_id) y ser analizado por la Activity de destino.
  • Comportamiento con la app en primer plano: cuando la app está en primer plano, FCM no muestra la notificación automáticamente, sino que invoca onMessageReceived de su app; mostrar o no la notificación y cómo navegar al pulsarla depende por completo de su app.
  • Método de verificación: durante las pruebas conjuntas, use primero intent:#Intent;action=android.intent.action.MAIN;end para confirmar que la cadena del canal funciona, y luego sustitúyalo por la action de negocio para verificar la navegación a la página de destino.

Recomendación a largo plazo: migre cuanto antes al SDK de EngageLab AppPush

La API de registro de dispositivos se concibe como una solución de compatibilidad y transición: permite alcanzar a los usuarios existentes de versiones históricas de la app sin integrar el SDK y genera un registration_id asociado, preparando el terreno para acceder después a otras capacidades de EngageLab AppPush. Resuelve la cuestión de "si se puede entregar", no sustituye al SDK.

Le recomendamos tratarla como parte de su estrategia de migración y no como solución a largo plazo:

  • Las nuevas versiones de la app integran el SDK de EngageLab AppPush: los nuevos usuarios obtienen su registration_id mediante el registro estándar del SDK y disfrutan directamente de todas las capacidades de visualización de notificaciones y gestión de clics.
  • Las versiones antiguas hacen la transición con tokens directos: los usuarios existentes siguen recibiendo envíos mediante el registration_id registrado con la API de registro de dispositivos; ambos sistemas pueden coexistir sin necesidad de fusionarlos a la fuerza.
  • Convergencia gradual con las actualizaciones: a medida que los usuarios actualizan a versiones con el SDK, los usuarios de tokens directos disminuyen de forma natural y todo termina unificado en el sistema del SDK.

En comparación con el método directo descrito en este artículo, tras integrar el SDK:

  • La navegación al pulsar la notificación la gestiona el SDK de forma unificada; los tres tipos que admite intent.url (Activity concreta, página de inicio de la app, Deeplink) no requieren que declare actions ni lógica de análisis una por una en su app;
  • La visualización de notificaciones en primer plano, los estilos de la barra de notificaciones (builder_id, style, channel_id, etc.), las insignias, la agrupación de mensajes y otros campos surten pleno efecto;
  • El SDK informa automáticamente de la información del dispositivo y de comportamientos como los clics, por lo que las estadísticas de entrega y de clics en la consola son más completas.

Para la integración, consulte la Guía de integración del SDK de Android y la Guía de integración del SDK de iOS.

Icon Solid Transparent White Qiyu
Contacto