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+
- Agregue la dependencia para las instalaciones de Firebase a su Podfile:
pod 'FirebaseInstallations'
- Ejecute
pod install
y abra el archivo.xcworkspace
creado. - Importe el módulo
FirebaseCore
en suUIApplicationDelegate
, 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; // ...
- Configure una instancia compartida
FirebaseApp
en el métodoapplication(_: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];
- Si está utilizando SwiftUI, debe crear un delegado de aplicación y adjuntarlo a su estructura
App
medianteUIApplicationDelegateAdaptor
oNSApplicationDelegateAdaptor
. 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.9.0/firebase-installations.js"></script>
Aleteo
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
Reconstruya su proyecto:
flutter run
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; } }];