Administrar instalaciones de Firebase

El servicio de instalaciones de Firebase (FIS) proporciona un ID de instalación de Firebase (FID) para cada instancia instalada de una aplicación de Firebase. Estos servicios de Firebase utilizan internamente el ID de instalación de Firebase:

Servicio de base de fuego Funcionalidad de instalaciones de Firebase
Mensajería en la nube de Firebase

Firebase Cloud Messaging utiliza los ID de instalación de Firebase para dirigirse a los dispositivos para la entrega de mensajes.

Crashlytics de base de fuego

Firebase Crashlytics rota el UUID de instalación de Crashlytics según los cambios en el ID de instalación de Firebase de la instancia de la aplicación. En el futuro, el ID de instalación se podrá utilizar para habilitar funciones que mejoren los servicios de informes y gestión de fallos.

Mensajería en la aplicación de Firebase

Firebase In-App Messaging utiliza los ID de instalación de Firebase para dirigirse a los dispositivos para la entrega de mensajes.

Monitoreo del rendimiento de Firebase

Performance Monitoring utiliza los ID de instalación de Firebase para calcular la cantidad de instalaciones únicas de Firebase que acceden a los recursos de la red, para garantizar que los patrones de acceso sean suficientemente anónimos. También utiliza los ID de instalación de Firebase con Firebase Remote Config para administrar la tasa de informes de eventos de rendimiento.

Configuración remota de Firebase

Remote Config usa los ID de instalación de Firebase para seleccionar valores de configuración para regresar a los dispositivos de los usuarios finales.

ML de base de fuego

Firebase ML utiliza credenciales llamadas tokens de autenticación de instalación para la autenticación del dispositivo cuando se interactúa con instancias de aplicaciones, por ejemplo, para distribuir modelos de desarrollador a instancias de aplicaciones.

Almacenamiento de segmentación de usuarios de Firebase

Firebase User Segmentation Storage almacena los ID de instalación de Firebase y los atributos y segmentos relacionados para proporcionar información de orientación a otros servicios de Firebase que los utilizan.

Normalmente, los servicios de Firebase utilizan el servicio de instalación de Firebase sin necesidad de que los desarrolladores interactúen directamente con la API de FIS. Sin embargo, hay casos en los que los desarrolladores de aplicaciones podrían querer llamar directamente a la API de FIS, como por ejemplo:

  • Para eliminar una instalación de Firebase y los datos vinculados a la instalación.
  • Para recuperar identificadores (ID de instalación de Firebase) para apuntar a instalaciones de aplicaciones específicas.
  • Para recuperar tokens de autenticación de instalación para autenticar las instalaciones de Firebase.

Para comenzar a llamar directamente a la API de FIS, agregue el SDK a su aplicación.

Agrega el SDK de instalaciones de Firebase a tu aplicación

iOS+

  1. Agregue la dependencia para las instalaciones de Firebase a su Podfile:
    pod 'FirebaseInstallations'
  2. Ejecute pod install y abra el archivo .xcworkspace creado.
  3. Importe el módulo FirebaseCore en su UIApplicationDelegate , así como cualquier otro módulo de Firebase que utilice el delegado de su aplicación. Por ejemplo, para usar Cloud Firestore y autenticación:

    Interfaz de usuario rápida

    import SwiftUI
    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Rápido

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    C objetivo

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  4. Configure una instancia compartida FirebaseApp en el método application(_:didFinishLaunchingWithOptions:) del delegado de su aplicación:

    Interfaz de usuario rápida

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    Rápido

    // Use Firebase library to configure APIs
    FirebaseApp.configure()

    C objetivo

    // Use Firebase library to configure APIs
    [FIRApp configure];
  5. Si está utilizando SwiftUI, debe crear un delegado de aplicación y adjuntarlo a su estructura App mediante UIApplicationDelegateAdaptor o NSApplicationDelegateAdaptor . También debes desactivar el cambio de delegados de aplicaciones. Para obtener más información, consulte las instrucciones de SwiftUI .

    Interfaz de usuario rápida

    @main
    struct YourApp: App {
      // register app delegate for Firebase setup
      @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
      var body: some Scene {
        WindowGroup {
          NavigationView {
            ContentView()
          }
        }
      }
    }
          

Androide

Agregue la dependencia para el SDK de Android de las instalaciones de Firebase al archivo Gradle de su módulo (nivel de aplicación) (generalmente app/build.gradle ):

implementation 'com.google.firebase:firebase-installations:17.2.0'

javascript

Dependiendo de cómo esté alojada su aplicación web, su configuración puede manejarse automáticamente o puede que necesite actualizar su objeto de configuración de Firebase .

Por ejemplo, si sus dependencias se agregan en index.html, agregue la dependencia en el elemento <head>:

<script src="/__/firebase/10.8.0/firebase-installations.js"></script>

Aleteo

  1. Desde el directorio raíz de su proyecto Flutter, ejecute el siguiente comando para instalar el complemento de instalación de Firebase:

    flutter pub add firebase_app_installations
    
  2. Reconstruya su proyecto:

    flutter run
    
  3. Importe el complemento de instalación de Firebase:

    import 'package:firebase_app_installations/firebase_app_installations.dart';
    

Eliminar una instalación de Firebase

Los datos vinculados a una instalación de Firebase generalmente no son de identificación personal. Aún así, puede resultar útil ofrecer a los usuarios la opción de administrar y eliminar estos datos.

Los ID de instalación de Firebase son diferentes para cada instalación de cada aplicación; diferentes aplicaciones en el mismo dispositivo tienen diferentes ID de instalación de Firebase. Los ID de instalación de Firebase identifican las instalaciones de aplicaciones y los datos vinculados a esas instalaciones.

Cuando eliminas un ID de instalación, los datos vinculados a ese ID de instalación se eliminan de los sistemas activos y de respaldo de todos los servicios de Firebase que usan los ID de instalación de Firebase para identificar las instalaciones dentro de los 180 días. Este proceso se describe en detalle en la declaración de Google sobre eliminación y retención .

A menos que desactive todos los servicios que generan FID en su aplicación, FIS crea una nueva ID en unos pocos días. Firebase considera que el ID recién creado es una nueva instalación de Firebase y no lo asocia con el ID o los datos anteriores de ninguna manera.

Eliminar un FID con una llamada a la API del cliente

Para eliminar los FID generados por los servicios de Firebase, llame al método apropiado desde el SDK de instalaciones de Firebase:

Rápido

do {
  try await Installations.installations().delete()
  print("Installation deleted");
} catch {
  print("Error deleting installation: \(error)")
}

C objetivo

[[FIRInstallations installations] deleteWithCompletion:^(NSError *error) {
   if (error != nil) {
     NSLog(@"Error deleting Installation %@", error);
     return;
   }
   NSLog(@"Installation deleted");
}];

Java

FirebaseInstallations.getInstance().delete()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        if (task.isSuccessful()) {
            Log.d("Installations", "Installation deleted");
        } else {
            Log.e("Installations", "Unable to delete Installation");
        }
    }
});

Kotlin+KTX

FirebaseInstallations.getInstance().delete().addOnCompleteListener { task ->
    if (task.isComplete) {
        Log.d("Installations", "Installation deleted")
    } else {
        Log.e("Installations", "Unable to delete Installation")
    }
}

javascript

await firebase.installations().delete();

Dart

await FirebaseInstallations.instance.delete();

Eliminar un FID con una llamada a la API del servidor

Para eliminar un FID con una llamada a la API del servidor, agregue el SDK de administrador de Firebase a su servidor , si aún no lo ha hecho.

Una vez que se agrega el SDK, elimine los FID mediante una llamada a la función de eliminación en el idioma de su elección (nota: excepto Node.js, estos métodos reflejan el nombre del ID de instancia. Sin embargo, todos eliminan el FID cuando se llama con cualquier Firebase actual SDK).

Nodo.js

// An FIDsent from a client service SDK
const idToDelete = 'eyJhbGciOiJFUzI1N_iIs5';

admin.installations().deleteInstallation(idToDelete);

Java

// An FID sent from a client service SDK
String idToDelete = "eyJhbGciOiJFUzI1N_iIs5";

FirebaseInstanceId.getInstance().deleteInstanceIdAsync(idToDelete).get();

Pitón

  from firebase_admin import instance_id

  # An FID sent from a client service SDK
  id_to_delete = 'eyJhbGciOiJFUzI1N_iIs5'

  instance_id.delete_instance_id(id_to_delete)

Ir

client, err := app.InstanceId(ctx)
if err != nil {
  log.Fatalln("error initializing client", err)
}

iidToDelete := "eyJhbGciOiJFUzI1N_iIs5"
if err := client.DeleteInstanceId(ctx, iidToDelete); err != nil {
  log.Fatalln("error deleting FID", err)
}

Cuando eliminas un ID de instalación de Firebase con una llamada a la API del servidor, los servicios de Firebase inician el proceso para eliminar los datos vinculados a ese ID de instalación, dejan de aceptar datos nuevos para ese ID en el transcurso de 1 a 2 días y luego notifican a la aplicación cliente. que la identificación fue eliminada. Hasta que Firebase notifique a la aplicación cliente, es posible que algunos de los servicios de la aplicación aún tengan como destino el ID; por ejemplo, una instalación de Firebase podría continuar recibiendo notificaciones de FCM durante algunas horas.

Si desea eliminar el ID de instalación actual de Firebase y usar inmediatamente los servicios de Firebase con un ID nuevo y no relacionado, use la API del cliente para manejar la eliminación.

Recuperar identificadores de clientes

Si necesita identificar instalaciones particulares de su aplicación, puede hacerlo recuperando el ID de instalación de Firebase. Por ejemplo, para crear segmentos de instalaciones de aplicaciones para la importación de BiqQuery o para realizar pruebas durante el desarrollo de Firebase In-App Messaging, puede identificar y orientar los dispositivos correctos utilizando los ID de instalación de Firebase correspondientes.

Para recuperar una ID de instalación de Firebase:

Rápido

do {
  let id = try await Installations.installations().installationID()
  print("Installation ID: \(id)")
} catch {
  print("Error fetching id: \(error)")
}

C objetivo

[[FIRInstallations installations] installationIDWithCompletion:^(NSString *identifier, NSError *error) {
  if (error != nil) {
    NSLog(@"Error fetching Installation ID %@", error);
    return;
  }
  NSLog(@"Installation ID: %@", identifier);
}];

Java

FirebaseInstallations.getInstance().getId()
        .addOnCompleteListener(new OnCompleteListener<String>() {
    @Override
    public void onComplete(@NonNull Task<String> task) {
        if (task.isSuccessful()) {
            Log.d("Installations", "Installation ID: " + task.getResult());
        } else {
            Log.e("Installations", "Unable to get Installation ID");
        }
    }
});

Kotlin+KTX

FirebaseInstallations.getInstance().id.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        Log.d("Installations", "Installation ID: " + task.result)
    } else {
        Log.e("Installations", "Unable to get Installation ID")
    }
}

javascript

const installationId = await firebase.installations().getId();
console.log(installationId);

Dart

String id = await FirebaseInstallations.instance.getId();

Recuperar tokens de autenticación de instalación

Los servicios de Firebase pueden autenticar las instalaciones de Firebase con tokens de autenticación recuperados de FIS. Por ejemplo, al diseñar pruebas A/B para Remote Config, puede autenticar un dispositivo de prueba específico mediante un token de autenticación de instalación.

Un token de autenticación de instalación es un token de portador de corta duración en formato de token web JSON (JWT) que contiene la siguiente información para una instalación:

  • El ID de instalación de Firebase
  • El proyecto asociado ( projectNumber )
  • El ID de la aplicación Firebase asociada ( appId )
  • La fecha de vencimiento del token.

Un token de autenticación de instalación no se puede revocar y sigue siendo válido hasta su fecha de vencimiento. La vida útil predeterminada del token es una semana.

Para recuperar un token de autenticación de instalación:

Rápido

do {
  let result = try await Installations.installations()
    .authTokenForcingRefresh(true)
  print("Installation auth token: \(result.authToken)")
} catch {
  print("Error fetching token: \(error)")
}

C objetivo

[[FIRInstallations installations] authTokenForcingRefresh:true
                                               completion:^(FIRInstallationsAuthTokenResult *result, NSError *error) {
  if (error != nil) {
    NSLog(@"Error fetching Installation token %@", error);
    return;
  }
  NSLog(@"Installation auth token: %@", [result authToken]);
}];

Java

FirebaseInstallations.getInstance().getToken(/* forceRefresh */true)
        .addOnCompleteListener(new OnCompleteListener<InstallationTokenResult>() {
    @Override
    public void onComplete(@NonNull Task<InstallationTokenResult> task) {
        if (task.isSuccessful() && task.getResult() != null) {
            Log.d("Installations", "Installation auth token: " + task.getResult().getToken());
        } else {
            Log.e("Installations", "Unable to get Installation auth token");
        }
    }
});

Kotlin+KTX

val forceRefresh = true
FirebaseInstallations.getInstance().getToken(forceRefresh)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            Log.d("Installations", "Installation auth token: " + task.result?.token)
        } else {
            Log.e("Installations", "Unable to get Installation auth token")
        }
    }

javascript

const installationToken = await firebase.installations()
    .getToken(/* forceRefresh */ true);
console.log(installationToken);

Dart

String token = await FirebaseInstallations.instance.getToken();

Supervisar el ciclo de vida del ID de instalación de Firebase

Durante el funcionamiento normal de una aplicación, los ID de instalación (FID) de Firebase no requieren un monitoreo especial. Sin embargo, las aplicaciones que recuperan y usan explícitamente FID deben agregar lógica para monitorear la posible eliminación o rotación del FID. A continuación se muestran algunos casos en los que los FID podrían eliminarse o rotarse:

  • Desinstalación o reinstalación de la aplicación, por ejemplo, cuando un usuario final la instala en un nuevo dispositivo.
  • El usuario final borra el caché de la aplicación o del dispositivo.
  • La eliminación de FID se activa en el backend debido a la inactividad de la aplicación (actualmente el umbral para esto es 270 días de inactividad).

Cuando las aplicaciones experimentan rotación o eliminación de FID en este tipo de casos, se les asigna un nuevo FID. Además, el token de autenticación de instalación asociado con un FID eliminado se elimina, independientemente de su madurez, y se reemplaza con un nuevo token de autenticación de instalación.

Las aplicaciones pueden monitorear estos cambios y responder en consecuencia.

Para monitorear la rotación del FID:

Rápido

installationIDObserver = NotificationCenter.default.addObserver(
        forName: .InstallationIDDidChange,
        object: nil,
        queue: nil
) { (notification) in
  // Fetch new Installation ID
  Task {
    await self.fetchInstallationToken()
  }
}

C objetivo

__weak __auto_type weakSelf = self;
self.installationIDObserver = [[NSNotificationCenter defaultCenter]
        addObserverForName: FIRInstallationIDDidChangeNotification
                    object:nil
                     queue:nil
                usingBlock:^(NSNotification * _Nonnull notification) {
    // Fetch new Installation ID
    [weakSelf fetchInstallationsID];
}];

Una NSNotification denominada NSNotificationName.InstallationIDDidChange se publica en el NSNotificationCenter predeterminado cada vez que se asigna un nuevo FID.

Androide

Los clientes de Kotlin y Java deben agregar lógica de reintento para responder a llamadas fallidas y recuperar el nuevo FID.

javascript

Las aplicaciones web pueden suscribirse al enlace onIdChange .

Cada vez que se crea un nuevo FID, se activa la devolución de llamada suscrita:

await firebase.installations().onIdChange((newId) => {
  console.log(newId);
  // TODO: Handle new installation ID.
});

Dart

FirebaseInstallations.instance.onIdChange.listen((token) {
  print('FID token: $token');
});

Migrar desde ID de instancia a instalaciones de Firebase

Antes de la introducción de las instalaciones de Firebase, Firebase dependía del SDK de ID de instancia para los identificadores de instalaciones de aplicaciones. Las instalaciones de Firebase brindan ventajas significativas sobre Instance ID en términos de confiabilidad, rendimiento y seguridad. Las aplicaciones de Firebase que dependen del SDK de ID de instancia deben migrar a las instalaciones de Firebase.

El proceso de migración es diferente según su aplicación:

  • Las aplicaciones que no llaman directamente a las API de ID de instancia pueden migrar actualizando sus versiones de SDK . La mayoría de las aplicaciones de Firebase entran en esta categoría.

  • Las aplicaciones que realizan llamadas API explícitamente a Instance ID deben actualizar las versiones del SDK y realizar cambios en el código para reemplazar los métodos de Instance ID con sus instalaciones de Firebase o equivalentes de FCM. Si su aplicación usa el ID de instancia para recuperar tokens de registro de FCM o usa explícitamente el ID de instancia para apuntar a instancias de la aplicación o para cualquier otro propósito, deberá actualizar el código de su aplicación.

Actualmente, FIS es compatible con versiones anteriores del identificador heredado Firebase Instance ID. Eliminar un IID es un método alternativo para solicitar la eliminación de datos con estos SDK de Firebase:

  • iOS 6.14.0 y anteriores
  • SDK de Android anteriores al 27 de febrero de 2020

Esto significa que no es necesario que las aplicaciones migren a instalaciones de Firebase; sin embargo, es muy recomendable hacerlo.

Actualización a versiones mínimas de SDK para instalaciones de Firebase

Para migrar de Instance ID a instalaciones de Firebase, asegúrese de que sus aplicaciones utilicen al menos los números de versión mínimos enumerados de los siguientes SDK de Firebase:

SDK de base de fuego Versión mínima de Android Versión mínima de iOS
Mensajería en la nube de Firebase v20.3.0 v6.34.0
Configuración remota v19.2.0 v6.24.0
Google Analytics para Firebase \ (SDK de medición) v17.4.4 v6.18.0
Mensajería en la aplicación v19.0.7 v6.24.0
Supervisión del rendimiento v19.0.8 v6.21.0
Crashlíticos v17.2.1 v6.23.0
Kit de aprendizaje automático v22.1.2 v6.28.0

Actualización de código que llama explícitamente a las API de ID de instancia

Si su aplicación de Android o Apple usa directamente métodos del SDK de ID de instancia, puede reemplazar ese uso con alternativas idénticas en el SDK de instalaciones de Firebase o el SDK de FCM.

Recuperar un identificador

Los métodos para obtener ID de instancia se reemplazan por métodos para obtener un ID de instalación. Por ejemplo:

Antes

Rápido

Messaging.messaging().token { token, error in
  if let error = error {
    print("Error fetching remote FCM registration token: \(error)")
  } else if let token = token {
    print("Remote instance ID token: \(token)")
    self.remoteFCMTokenMessage.text = "Remote FCM registration token: \(token)"
  }
}

C objetivo

[[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) {
   if (error != nil) {
     NSLog(@"Error fetching the remote FCM registration token: %@", error);
   } else {
     NSLog(@"Remote FCM registration token: %@", token);
     NSString* message =
       [NSString stringWithFormat:@"FCM registration token: %@", token];
     self.remoteFCMTokenMessage.text = message;
   }
 }];

Java

FirebaseInstanceId.getInstance().getInstanceId()
        .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
            @Override
            public void onComplete(@NonNull Task<InstanceIdResult> task) {
                Log.d("IID_TOKEN", task.getResult().getToken());
            }
        });

Kotlin+KTX

FirebaseInstanceId.getInstance().instanceId
        .addOnSuccessListener { result ->
            Log.d("IID_TOKEN", result.token)
        }

Después

Rápido

do {
  let id = try await Installations.installations().installationID()
  print("Installation ID: \(id)")
} catch {
  print("Error fetching id: \(error)")
}

C objetivo

[[FIRInstallations installations] installationIDWithCompletion:^(NSString *identifier, NSError *error) {
  if (error != nil) {
    NSLog(@"Error fetching Installation ID %@", error);
    return;
  }
  NSLog(@"Installation ID: %@", identifier);
}];

Java

FirebaseInstallations.getInstance().getId()
        .addOnCompleteListener(new OnCompleteListener<String>() {
    @Override
    public void onComplete(@NonNull Task<String> task) {
        if (task.isSuccessful()) {
            Log.d("Installations", "Installation ID: " + task.getResult());
        } else {
            Log.e("Installations", "Unable to get Installation ID");
        }
    }
});

Kotlin+KTX

FirebaseInstallations.getInstance().id.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        Log.d("Installations", "Installation ID: " + task.result)
    } else {
        Log.e("Installations", "Unable to get Installation ID")
    }
}

Eliminar un identificador

Los métodos para eliminar ID de instancia se reemplazan por métodos para eliminar ID de instalación de Firebase. Por ejemplo:

Antes

Rápido

InstanceID.instanceID().deleteID { error in
  if let error = error {
    print("Error deleting instance ID: \(error)")
  }
}

C objetivo

[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError *error) {
  if error != nil {
    NSLog(@"Error deleting instance ID: %@", error);
  }
}];

Androide

FirebaseInstanceId.deleteInstanceId();

Después

Rápido

func delete(completion: @escaping (Error?) -> Void)

C objetivo

- (void)deleteWithCompletion:(nonnull void (^)(NSError *_Nullable))completion;

Java

FirebaseInstallations.getInstance().delete()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        if (task.isSuccessful()) {
            Log.d("Installations", "Installation deleted");
        } else {
            Log.e("Installations", "Unable to delete Installation");
        }
    }
});

Kotlin+KTX

FirebaseInstallations.getInstance().delete().addOnCompleteListener { task ->
    if (task.isComplete) {
        Log.d("Installations", "Installation deleted")
    } else {
        Log.e("Installations", "Unable to delete Installation")
    }
}

Recuperar un token de registro de FCM

Antes de la introducción de Firebase Installations, los clientes de FCM recuperaban tokens de registro del ID de instancia. Ahora, el SDK de FCM proporciona métodos para recuperar el token de registro.

Antes

Java

FirebaseInstanceId.getInstance().getInstanceId()
        .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
            @Override
            public void onComplete(@NonNull Task<InstanceIdResult> task) {
                if (!task.isSuccessful()) {
                    Log.w(TAG, "getInstanceId failed", task.getException());
                    return;
                }

                // Get new Instance ID token
                String token = task.getResult().getToken();

                // 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();
            }
        });

Kotlin+KTX

FirebaseInstanceId.getInstance().instanceId
        .addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w(TAG, "getInstanceId failed", task.exception)
                return@OnCompleteListener
            }

            // Get new Instance ID token
            val token = task.result?.token

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

Rápido

Messaging.messaging().token { token, error in
  if let error = error {
    print("Error fetching remote FCM registration token: \(error)")
  } else if let token = token {
    print("Remote instance ID token: \(token)")
    self.remoteFCMTokenMessage.text = "Remote FCM registration token: \(token)"
  }
}

C objetivo

[[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) {
   if (error != nil) {
     NSLog(@"Error fetching the remote FCM registration token: %@", error);
   } else {
     NSLog(@"Remote FCM registration token: %@", token);
     NSString* message =
       [NSString stringWithFormat:@"FCM registration token: %@", token];
     self.remoteFCMTokenMessage.text = message;
   }
 }];

Después

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();
        }
    });

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()
})

Rápido

Messaging.messaging().token { token, error in
  if let error = error {
    print("Error fetching FCM registration token: \(error)")
  } else if let token = token {
    print("FCM registration token: \(token)")
    self.fcmRegTokenMessage.text  = "Remote FCM registration token: \(token)"
  }
}

C objetivo

[[FIRMessaging messaging] tokenWithCompletion:^(NSString *token, NSError *error) {
  if (error != nil) {
    NSLog(@"Error getting FCM registration token: %@", error);
  } else {
    NSLog(@"FCM registration token: %@", token);
    self.fcmRegTokenMessage.text = token;
  }
}];