Ir a la consola

Recibe mensajes en una app para Android

Las notificaciones de Firebase se comportan de diferente manera, según el estado de primer plano o segundo plano de la app que las recibe. Si quieres que las apps en primer plano reciban mensajes de notificación o mensajes de datos, deberás escribir código para administrar la devolución de llamada onMessageReceived. Para ver una explicación de la diferencia entre los mensajes de notificación y los de datos, consulta los tipos de mensaje.

Administración de mensajes

Para recibir mensajes, usa un servicio que extienda FirebaseMessagingService. El servicio debe anular las devoluciones de llamada onMessageReceived y onDeletedMessages. Debe administrar cualquier mensaje en un plazo de 20 segundos desde su recepción (10 segundos en Android Marshmallow). El margen de tiempo puede ser más breve según los retrasos del SO incurridos antes de llamar a onMessageReceived. Después de ese tiempo, varios comportamientos del SO, como los límites de ejecución en segundo plano de Android O, pueden interferir en tu capacidad para finalizar el trabajo. Si deseas obtener más información, consulta la descripción general en la prioridad del mensaje.

onMessageReceived se proporciona para la mayoría de los tipos de mensajes, con las siguientes excepciones:

  • Mensajes de notificación enviados cuando la app está en segundo plano. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo. Cuando un usuario presiona una notificación, abre el selector de aplicaciones de forma predeterminada.

  • Mensajes con carga útil de notificaciones y datos cuando se reciben en segundo plano. En este caso, la notificación se entrega a la bandeja del sistema del dispositivo y la carga útil de datos se entrega en los adicionales del intent de tu actividad iniciadora.

Resumen:

Estado de la app Notificación Datos Ambos
Primer plano onMessageReceived onMessageReceived onMessageReceived
Segundo plano Bandeja del sistema onMessageReceived Notificación: Bandeja del sistema
Datos: En extras del intent
Para obtener más información acerca de los tipos de mensajes, consulta Mensajes de notificación y de datos.

Edita el manifiesto de la app

Para usar FirebaseMessagingService, debes agregar lo siguiente al manifiesto de tu app:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Además, te recomendamos establecer valores predeterminados para personalizar el aspecto de las notificaciones. Puedes especificar un ícono y un color predeterminados y personalizados que se aplican cada vez que no se establecen valores equivalentes en la carga útil de notificación.

Agrega estas líneas en la etiqueta application para establecer el ícono predeterminado y el color personalizado:

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

Android muestra el ícono predeterminado personalizado para lo siguiente:

  • Todos los mensajes de notificación enviados desde el Compositor de Notifications.
  • Todos los mensajes de notificación que no establecen el ícono de manera explícita en la carga útil de la notificación.

Android usa el color predeterminado personalizado para lo siguiente:

  • Todos los mensajes de notificación enviados desde el Compositor de Notifications.
  • Todos los mensajes de notificación que no definen el color de manera explícita en la carga útil de la notificación.

Si no hay un ícono predeterminado personalizado y no se establece un ícono en la carga útil de la notificación, Android muestra el ícono de la aplicación en blanco.

Anula onMessageReceived

Puedes anular el método FirebaseMessagingService.onMessageReceived para realizar acciones según el objeto RemoteMessage recibido y obtener los datos del mensaje:

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // ...

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // ...

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    remoteMessage.data.isNotEmpty().let {
        Log.d(TAG, "Message data payload: " + remoteMessage.data)

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Anula onDeletedMessages

En algunas situaciones, es posible que FCM no envíe un mensaje. Esto ocurre cuando hay muchos mensajes (más de 100) pendientes para tu app en un dispositivo específico al momento de conectarse o si el dispositivo no se conecta a FCM en más de un mes. En estos casos, es posible que recibas una devolución de llamada a FirebaseMessagingService.onDeletedMessages(). Cuando la instancia de app recibe esta devolución de llamada, debería ejecutar una sincronización completa con tu servidor de apps. Si no enviaste un mensaje a la app en ese dispositivo en las últimas 4 semanas, FCM no llamará a onDeletedMessages().

Maneja mensajes de notificación en una app en segundo plano

Cuando tu app está en segundo plano, Android dirige los mensajes de notificación a la bandeja del sistema. Cuando un usuario presiona una notificación, se abre el selector de aplicaciones de forma predeterminada.

Esto incluye los mensajes que contienen carga útil de notificaciones y datos (y todos los mensajes que se envíen desde la consola de Notifications). En estos casos, la notificación se entrega a la bandeja del sistema del dispositivo, y la carga de datos útil se entrega en los adicionales del intent de tu actividad iniciadora.

Para obtener estadísticas de la entrega de mensajes a tu app, consulta el panel de mensajes de FCM que registra la cantidad de mensajes enviados y abiertos en dispositivos iOS y Android, junto con datos de “impresiones” (notificaciones vistas por los usuarios) para apps de Android.

Aplicaciones con restricción en segundo plano (Android P o versiones posteriores)

A partir de enero de 2019, FCM no entregará mensajes a las aplicaciones que el usuario configuró con restricción en segundo plano (por ejemplo, mediante Configuración -> Apps y notificaciones -> [Nombre de la app] -> Batería). Cuando se quite la restricción en segundo plano de tu app, esta podrá recibir mensajes nuevos como antes. Para evitar que se pierdan los mensajes y otras consecuencias de la restricción en segundo plano, asegúrate de evitar los comportamientos incorrectos que se indican en la iniciativa Android vitals. Estos comportamientos podrían causar que el dispositivo Android recomiende al usuario que configure la restricción en segundo plano para tu app. Puedes comprobar si tu app tiene habilitada la restricción en segundo plano mediante el método isBackgroundRestricted().