Configura una app cliente de Firebase Cloud Messaging en Android

Los clientes de FCM deben tener dispositivos con Android 4.4 o una versión más reciente que también tenga la app Google Play Store instalada o un emulador que ejecute Android 4.4 con las APIs de Google. Ten en cuenta que tienes otras opciones además de implementar tus apps para Android a través de Google Play Store.

Configura el SDK

Es posible que hayas completado tareas que aparecen en esta sección si ya habilitaste otras funciones de Firebase para tu app. Si aún no lo has hecho, agrega Firebase a tu proyecto de Android.

Edita el manifiesto de tu app

Agrega lo siguiente al manifiesto de tu app:

  • Un servicio que extienda FirebaseMessagingService. Esto es obligatorio si deseas administrar los mensajes además de recibir notificaciones en apps en segundo plano. Para recibir notificaciones en apps en primer plano, recibir la carga útil de datos, enviar mensajes upstream, etc., debes extender este servicio.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • Dentro del componente de la aplicación, elementos de metadatos para configurar el ícono y el color predeterminados de la notificación (opcional). Android usa estos valores cada vez que los mensajes entrantes no tienen un ícono ni un color configurado de manera explícita.
  • <!-- 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" />
  • A partir de Android 8.0 (nivel de API 26) y versiones más recientes, se admiten y se recomiendan los canales de notificaciones (opcional). FCM proporciona un canal de notificaciones predeterminado con configuración básica. Si prefieres crear y usar tu propio canal predeterminado, configura default_notification_channel_id con el ID de tu objeto de canal de notificaciones, como se muestra en el ejemplo. FCM usará este valor cada vez que los mensajes entrantes no tengan configurado un canal de notificaciones de manera explícita. Para obtener más información, consulta cómo administrar canales de notificaciones.
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

Solicita permisos de notificaciones del tiempo de ejecución en Android 13 y versiones posteriores

Android 13 presenta un nuevo permiso de tiempo de ejecución para mostrar notificaciones. Este afecta a todas las apps que se ejecutan en Android 13 o versiones posteriores y que usan notificaciones de FCM.

De forma predeterminada, el SDK de FCM (versión 23.0.6 o posterior) incluye el permiso POST_NOTIFICATIONS definido en el manifiesto. Sin embargo, tu app también deberá solicitar la versión del tiempo de ejecución de este permiso a través de la constante android.permission.POST_NOTIFICATIONS. La app no podrá mostrar notificaciones hasta que el usuario otorgue el permiso.

Para solicitar el nuevo permiso de tiempo de ejecución, haz lo siguiente:

Kotlin+KTX

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

Por lo general, debes mostrar una IU que explique al usuario las funciones que se habilitarán si otorga permisos para que la app publique notificaciones. La IU debe proporcionar al usuario las opciones para aceptar o rechazar, como los botones Aceptar y No, gracias. Si el usuario selecciona Aceptar, solicita directamente el permiso. Si el usuario selecciona No, gracias, permite que continúe sin notificaciones.

Consulta Permiso de tiempo de ejecución de notificaciones para conocer más prácticas recomendadas sobre cuándo tu app debe solicitar el permiso POST_NOTIFICATIONS al usuario.

Permisos de notificaciones para apps dirigidas a Android 12L (nivel de API 32) o versiones anteriores

La primera vez que la app cree un canal de notificaciones, Android solicitará automáticamente permiso al usuario, siempre y cuando la aplicación esté en primer plano. Sin embargo, existen advertencias importantes que se deben tener en cuenta sobre el momento de la creación del canal y las solicitudes de permisos:

  • Si tu app crea su primer canal de notificaciones cuando se ejecuta en segundo plano (lo que hace el SDK de FCM cuando recibe una notificación de FCM), Android no permitirá que se muestre la notificación ni solicitará permisos de notificaciones al usuario hasta la próxima vez que se abra la app. Es decir, se perderán todas las notificaciones recibidas antes de que se abra la app y el usuario acepte el permiso.
  • Recomendamos que actualices tu app para dirigirla a Android 13 y versiones posteriores a fin de aprovechar las APIs de la plataforma para solicitar permisos. Si eso no es posible, tu app debería crear canales de notificaciones antes de que envíes notificaciones a la app para activar el diálogo de permisos de notificaciones y asegurarte de que no se pierdan. Si quieres obtener más información, consulta las prácticas recomendadas para permisos de notificaciones.

Opcional: Quita el permiso POST_NOTIFICATIONS

De forma predeterminada, el SDK de FCM incluye el permiso POST_NOTIFICATIONS. Si tu app no usa mensajes de notificaciones (ya sea mediante notificaciones de FCM, a través de otro SDK o directamente publicados por la app) y no quieres que incluya el permiso, puedes quitarlo con el marcador de combinación del manifiesto remove. Ten en cuenta que quitar este permiso evita que se muestren todas las notificaciones, no solo las de FCM. Agrega lo siguiente al archivo de manifiesto de tu app:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

Accede al token de registro de dispositivo

Cuando se inicia tu app por primera vez, el SDK de FCM genera un token de registro para la instancia de la app cliente. Si el objetivo son dispositivos individuales o la creación de grupos de dispositivos, es necesario extender FirebaseMessagingService y anular onNewToken para acceder a este token.

En esta sección, se describe cómo recuperar el token y cómo supervisar los cambios que lo afectan. Debido a que el token se puede rotar después del primer inicio, te recomendamos enfáticamente que recuperes el token de registro con la actualización más reciente.

El token de registro puede cambiar en las siguientes situaciones:

  • La app se restablece en un dispositivo nuevo.
  • El usuario desinstala y vuelve a instalar la app.
  • El usuario borra los datos de la app.

Recupera el token de registro actual

Para recuperar el token actual, llama a FirebaseMessaging.getInstance().getToken().

Kotlin+KTX

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

Supervisa la generación de tokens

La devolución de llamada de onNewToken se activa cuando se genera un token nuevo.

Kotlin+KTX

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration token is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

Después de obtener el token, puedes enviarlo a tu servidor de apps y almacenarlo con tu método preferido.

Verificación de los Servicios de Google Play

Las apps que usan el SDK de los Servicios de Play siempre deben revisar el dispositivo para buscar un APK de Servicios de Google Play compatible antes de acceder a las funciones de los Servicios de Google Play. Se recomienda hacer esto en dos lugares: en el método onCreate() de la actividad principal y en su método onResume(). La verificación de onCreate() garantiza que la app no se pueda usar sin una verificación correcta. La verificación de onResume() garantiza que, si el usuario vuelve a la app en ejecución de alguna otra forma (por ejemplo, con el botón Atrás), la verificación se ejecute de todos modos.

Si el dispositivo no tiene una versión compatible de los Servicios de Google Play, tu app puede llamar a GoogleApiAvailability.makeGooglePlayServicesAvailable() para permitir que los usuarios descarguen tales servicios desde Play Store.

Evita la inicialización automática

Cuando se genera un token de registro de FCM, la biblioteca sube el identificador y los datos de configuración a Firebase. Si prefieres que no se generen tokens automáticamente, inhabilita la recopilación de Analytics y la inicialización automática de FCM (debes inhabilitar ambas funciones). Para ello, agrega los siguientes valores de metadatos al archivo AndroidManifest.xml:

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

Para volver a habilitar la inicialización automática de FCM, realiza una llamada de tiempo de ejecución:

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Para volver a habilitar la recopilación de Analytics, llama al método setAnalyticsCollectionEnabled() de la clase FirebaseAnalytics. Por ejemplo:

setAnalyticsCollectionEnabled(true);

Los valores establecidos se mantienen entre los reinicios de la app.

Próximos pasos

Cuando la app cliente esté configurada, estarás listo para comenzar a enviar mensajes downstream con el Compositor de Notifications. Esta función se presenta en la muestra de inicio rápido, que puedes descargar, ejecutar y revisar.

Con el fin de agregar otro comportamiento más avanzado a tu app, puedes declarar un filtro de intents y, luego, implementar una actividad para responder a los mensajes entrantes. Para obtener información detallada, consulta las guías en las que se explica cómo enviar mensajes desde un servidor de apps.

Ten en cuenta que, para aprovechar estas funciones, necesitarás una implementación de servidor y los protocolos del servidor (HTTP o XMPP), o una implementación del SDK de Admin.