El servicio de instalaciones de Firebase (FIS) proporciona un ID de instalación de Firebase (FID) para cada instancia instalada de una app de Firebase. Los siguientes servicios de Firebase usan de forma interna este ID de instalación de Firebase:
Servicio de Firebase | Funcionalidad de instalación de Firebase |
---|---|
Firebase Cloud Messaging |
Firebase Cloud Messaging usa los IDs de instalación de Firebase para segmentar los dispositivos a fin de entregar mensajes. |
Firebase Crashlytics |
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 app. En el futuro, es posible que el ID de instalación se use para habilitar funciones que mejoren los informes de fallas y los servicios de administración de fallas. |
Firebase In‑App Messaging |
Firebase In‑App Messaging usa los IDs de instalación de Firebase para segmentar los dispositivos a fin de entregar mensajes. |
Firebase Performance Monitoring |
Performance Monitoring usa los IDs de instalación de Firebase para calcular la cantidad de instalaciones únicas de Firebase que acceden a los recursos de red, a fin de garantizar que los patrones de acceso sean suficientemente anónimos. También usa los IDs de instalación de Firebase con Firebase Remote Config para administrar la tasa de informes de eventos de rendimiento. |
Firebase Remote Config |
Remote Config usa los IDs de instalación de Firebase para seleccionar valores de configuración que se mostrarán a los dispositivos del usuario final. |
AA de Firebase |
El AA de Firebase usa credenciales llamadas tokens de autenticación de instalación para autenticar dispositivos cuando se interactúa con instancias de apps, por ejemplo, a fin de distribuir modelos de desarrollador a instancias de apps. |
Firebase User Segmentation Storage |
Firebase User Segmentation Storage almacena los IDs de instalación de Firebase y los atributos y segmentos relacionados para proporcionar información de segmentación a otros servicios de Firebase que los usan. |
Por lo general, los servicios de Firebase usan el servicio de instalaciones de Firebase sin que los desarrolladores deban interactuar directamente con la API de FIS. Sin embargo, hay algunos casos en los que los desarrolladores de apps podrían querer llamar de forma directa a la API de FIS, como en los siguientes:
- Para borrar una instalación de Firebase y los datos vinculados a la instalación
- Para recuperar identificadores (IDs de instalación de Firebase) para segmentarse a instalaciones específicas de apps
- Para recuperar tokens de autenticación de instalación a fin de autenticar instalaciones de Firebase
Para comenzar a llamar de manera directa a la API del FIS, agrega el SDK a tu app.
Agrega el SDK de instalaciones de Firebase a tu app
iOS+
- Sigue estos pasos para agregar al Podfile la dependencia de las instalaciones de Firebase:
pod 'FirebaseInstallations'
- Ejecuta
pod install
y abre el archivo.xcworkspace
creado. - Importa el módulo
FirebaseCore
en tuUIApplicationDelegate
, así como cualquier otro módulo de Firebase que use el delegado de la app. Por ejemplo, para usar Cloud Firestore y Authentication:SwiftUI
import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Swift
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Objective-C
@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ...
- Configura una instancia compartida de
FirebaseApp
en el métodoapplication(_:didFinishLaunchingWithOptions:)
del delegado de la app:SwiftUI
// Use Firebase library to configure APIs FirebaseApp.configure()
Swift
// Use Firebase library to configure APIs FirebaseApp.configure()
Objective-C
// Use Firebase library to configure APIs [FIRApp configure];
- Si usas SwiftUI, debes crear un delegado de la aplicación y adjuntarlo
al struct de tu
App
a través deUIApplicationDelegateAdaptor
oNSApplicationDelegateAdaptor
. También debes inhabilitar el swizzling del delegado de la app. Para obtener más información, consulta las instrucciones de SwiftUI.SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Android
Agrega la dependencia del SDK de Android para las instalaciones de Firebase al archivo Gradle (generalmente app/build.gradle
) de tu módulo (a nivel de la app):
implementation 'com.google.firebase:firebase-installations:17.1.4'
JavaScript
En función de cómo esté alojada tu aplicación web, es posible que la configuración se controle de forma automática o que debas actualizar tu objeto de configuración de Firebase.
Por ejemplo, si tus dependencias se agregan a index.html, agrégalas al elemento <head>:
<script src="/__/firebase/10.4.0/firebase-installations.js"></script>
Flutter
Desde el directorio raíz de tu proyecto de Flutter, ejecuta el siguiente comando para instalar el complemento de instalaciones de Firebase:
flutter pub add firebase_app_installations
Vuelve a crear tu proyecto:
flutter run
Importa el complemento de instalaciones de Firebase:
import 'package:firebase_app_installations/firebase_app_installations.dart';
Borra una instalación de Firebase
Por lo general, los datos vinculados a una instalación de Firebase no identifican de forma personal. Sin embargo, puede ser útil proporcionarles a los usuarios la opción de administrar y borrar estos datos.
Los IDs de instalación de Firebase son diferentes para la instalación de cada app. Distintas aplicaciones en un mismo dispositivo tienen diferentes IDs de instalación de Firebase. Los IDs de instalación de Firebase identifican las instalaciones y los datos de app vinculados a esas instalaciones.
Cuando borras un ID de instalación, los datos vinculados a este se quitan de los sistemas activos y de copia de seguridad de todos los servicios de Firebase que usan IDs de instalación de Firebase para identificar instalaciones en un plazo de 180 días. Este proceso se describe de forma general en la declaración de Google sobre la eliminación y retención.
Si no inhabilitas todos los servicios generadores de FID en tu app, el FIS crea un ID nuevo después de unos días. Firebase considera que el ID recién creado es una instalación nueva de Firebase y no lo asocia de ninguna manera con el ID ni los datos anteriores.
Borra un FID mediante una llamada a la API del cliente
Para borrar los FID que generan los servicios de Firebase, llama al método apropiado desde el SDK de las instalaciones de Firebase:
Swift
Installations.installations().delete { error in if let error = error { print("Error deleting installation: \(error)") return } print("Installation deleted"); }
Objective‑C
[[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();
Borra un FID mediante una llamada a la API del servidor
Para borrar un FID con una llamada a la API del servidor, agrega el SDK de Firebase Admin a tu servidor, si aún no lo has hecho.
Una vez agregado, borra los FID mediante una llamada a la función de eliminación en el lenguaje de tu preferencia (ten en cuenta que, excepto para Node.js, aunque estos métodos reflejan la denominación del ID de instancia, en realidad borran el FID cuando se los llama con cualquier SDK de Firebase actual).
Node.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();
Python
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)
Go
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 borras un ID de instalación de Firebase con una llamada a la API del servidor, los servicios de Firebase comienzan el proceso para borrar los datos vinculados al ID de instalación, dejan de aceptar datos nuevos para ese ID durante 1 o 2 días y, luego, notifican a la app cliente que se borró el ID. Hasta que Firebase notifique a la app cliente, es posible que algunos de los servicios de la app aún se orienten al ID. Por ejemplo, una instalación de Firebase puede seguir recibiendo notificaciones de FCM durante unas horas.
Si deseas borrar el ID de instalación actual de Firebase y usar los servicios de Firebase de inmediato con un ID nuevo que no tenga ninguna relación, usa la API del cliente para controlar esta acción.
Recupera identificadores de clientes
Puedes identificar instalaciones específicas de tu app recuperando el ID de instalación de Firebase. Por ejemplo, para crear segmentos de instalaciones de apps para la importación de BigQuery o realizar pruebas durante el desarrollo de Firebase In‐App Messaging, puedes identificar y orientar los dispositivos correctos con los IDs de instalación de Firebase correspondientes.
Sigue estos pasos para recuperar un ID de instalación de Firebase:
Swift
Installations.installations().installationID { (id, error) in if let error = error { print("Error fetching id: \(error)") return } guard let id = id else { return } print("Installation ID: \(id)") }
Objective‑C
[[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();
Recupera tokens de autenticación de instalación
Los servicios de Firebase pueden autenticar instalaciones de Firebase con tokens de autenticación recuperados del FIS. Por ejemplo, cuando diseñas pruebas A/B para Remote Config, puedes autenticar un dispositivo de prueba orientado con un token de autenticación de instalación.
Los tokens de autenticación de instalación son tokens del portador de corta duración en formato de token web JSON (JWT) que contienen la siguiente información sobre una instalación:
- El ID de instalación de Firebase
- El proyecto asociado (
projectNumber
) - El ID de aplicación de Firebase asociado (
appId
) - La fecha de vencimiento del token
Los tokens de autenticación de instalación no pueden revocarse y son válidos hasta su fecha de vencimiento. La vida útil predeterminada de los tokens es de una semana.
Usa este código para recuperar un token de autenticación de instalación:
Swift
Installations.installations().authTokenForcingRefresh(true, completion: { (result, error) in if let error = error { print("Error fetching token: \(error)") return } guard let result = result else { return } print("Installation auth token: \(result.authToken)") })
Objective‑C
[[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();
Supervisa el ciclo de vida de los IDs de instalación de Firebase
Durante el funcionamiento normal de una app, los IDs de instalación de Firebase (FID) no requieren supervisión especial. Sin embargo, las apps que recuperan y usan FID de forma explícita deben agregar lógica para supervisar la posible eliminación o rotación de los FID. Estos son algunos casos en los que se podrían borrar o rotar los FID:
- Si se desinstala o vuelve a instalar la app (por ejemplo, cuando un usuario final la instala en un dispositivo nuevo)
- Si el usuario final borra la caché de la app o del dispositivo
- Si la eliminación de los FID se activa en el backend debido a inactividad en la app (actualmente, el umbral de inactividad es de 270 días)
Cuando las apps experimentan la rotación o eliminación de los FID en estos casos, se les asigna un FID nuevo. Además, se borra el token de autenticación de la instalación de Firebase asociado con el FID borrado (independientemente de su madurez) y se reemplaza por un nuevo token de autenticación de la instalación.
Las apps pueden supervisar estos cambios y responder en consecuencia.
Para supervisar la rotación de los FID, haz lo siguiente:
Swift
installationIDObserver = NotificationCenter.default.addObserver( forName: .InstallationIDDidChange, object: nil, queue: nil ) { (notification) in // Fetch new Installation ID self.fetchInstallationToken() }
Objective‑C
__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]; }];
Cada vez que se asigna un FID nuevo, se publica una NSNotification llamada NSNotificationName.InstallationIDDidChange
en el NSNotificationCenter predeterminado.
Android
Los clientes de Kotlin y Java deben agregar la lógica de reintento para responder las llamadas con errores a fin de recuperar el FID nuevo.
JavaScript
Las apps web pueden suscribirse al hook de onIdChange
.
Cada vez que se crea un FID nuevo, 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');
});
Migra del ID de instancia a instalaciones de Firebase
Antes del lanzamiento de las instalaciones de Firebase, Firebase dependía del SDK de Instance ID para los identificadores de instalaciones de apps. Las instalaciones de Firebase proporcionan ventajas significativas frente al ID de instancia en términos de confiabilidad, rendimiento y seguridad. Las apps de Firebase que dependen del SDK de Instance ID deben migrar a las instalaciones de Firebase.
El proceso de migración es diferente según la app:
Las apps que no llaman directamente a las APIs de Instance ID se pueden migrar actualizando las versiones del SDK. La mayoría de las apps de Firebase corresponden a esta clasificación.
En el caso de las apps que realizan llamadas a la API de Instance ID de forma explícita, se deben actualizar las versiones del SDK y realizar cambios en el código para reemplazar los métodos del ID de instancia con sus instalaciones de Firebase o equivalentes de FCM. Si tu app usa el ID de instancia para recuperar tokens de registro de FCM o lo utiliza explícitamente con el fin de segmentar las instancias de la app o para cualquier otro propósito, deberás actualizar el código de la aplicación.
Actualmente, el FIS tiene retrocompatibilidad con el identificador heredado del ID de instancia de Firebase. Borrar un IID es un método alternativo para solicitar la eliminación de datos con estos SDK de Firebase:
- iOS 6.14.0 y versiones anteriores
- SDK de Android anteriores al 27 de febrero de 2020
Esto significa que no es obligatorio que las apps se migren a las instalaciones de Firebase. Sin embargo, se recomienda hacerlo.
Actualiza a las versiones mínimas del SDK para las instalaciones de Firebase
Para migrar del ID de instancia a las instalaciones de Firebase, asegúrate de que las aplicaciones usen al menos las versiones mínimas de los siguientes SDK de Firebase:
SDK de Firebase | Versión mínima de Android | Versión mínima de iOS |
Firebase Cloud Messaging | v20.3.0 | v6.34.0 |
Remote Config | v19.2.0 | v6.24.0 |
Google Analytics para Firebase/(SDK de Measurement) | v17.4.4 | v6.18.0 |
In‑App Messaging | v19.0.7 | v6.24.0 |
Performance Monitoring | v19.0.8 | v6.21.0 |
Crashlytics | v17.2.1 | v6.23.0 |
ML Kit | v22.1.2 | v6.28.0 |
Actualiza el código que llama de manera explícita a las APIs de Instance ID
Si tu app para Android o Apple usa directamente los métodos del SDK de Instance ID, puedes reemplazar ese uso por alternativas idénticas que ofrece el SDK de instalaciones de Firebase o el SDK de FCM.
Recupera un identificador
Los métodos para obtener los IDs de instancia se reemplazan por métodos para obtener un ID de instalación. Por ejemplo:
Antes
Swift
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)" } }
Objective‑C
[[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
Swift
Installations.installations().installationID { (id, error) in if let error = error { print("Error fetching id: \(error)") return } guard let id = id else { return } print("Installation ID: \(id)") }
Objective‑C
[[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") } }
Borra un identificador
Los métodos para borrar los IDs de instancia se reemplazan por métodos para borrar los IDs de instalación de Firebase. Por ejemplo:
Antes
Swift
InstanceID.instanceID().deleteID { error in
if let error = error {
print("Error deleting instance ID: \(error)")
}
}
Objective-C
[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError *error) {
if error != nil {
NSLog(@"Error deleting instance ID: %@", error);
}
}];
Android
FirebaseInstanceId.deleteInstanceId();
Después
Swift
func delete(completion: @escaping (Error?) -> Void)
Objective‑C
- (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") } }
Recupera un token de registro de FCM
Antes del lanzamiento de las instalaciones de Firebase, los clientes de FCM recuperaban tokens de registro desde el 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() })
Swift
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)" } }
Objective‑C
[[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() })
Swift
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)" } }
Objective-C
[[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; } }];