Управление установками Firebase

Служба установки Firebase (FIS) предоставляет идентификатор установки Firebase (FID) для каждого установленного экземпляра приложения Firebase. Идентификатор установки Firebase используется внутри следующих служб Firebase:

Сервис Firebase Функциональность установки Firebase
Firebase Cloud Messaging

Firebase Cloud Messaging использует идентификаторы установок Firebase для определения целевых устройств для доставки сообщений.

Firebase Crashlytics

Firebase Crashlytics меняет UUID установки Crashlytics в зависимости от изменений идентификатора установки Firebase для экземпляра приложения. В будущем идентификатор установки может использоваться для включения функций, улучшающих отчеты о сбоях и службы управления сбоями.

Firebase In-App Messaging

Firebase In-App Messaging использует идентификаторы установок Firebase для определения целевых устройств для доставки сообщений.

Firebase Performance Monitoring

Performance Monitoring использует идентификаторы установок Firebase для расчета количества уникальных установок Firebase, обращающихся к сетевым ресурсам, чтобы обеспечить достаточную анонимность шаблонов доступа. Он также использует идентификаторы установок Firebase с Firebase Remote Config для управления частотой отправки отчетов о событиях производительности.

Firebase Remote Config

Remote Config использует идентификаторы установок Firebase для выбора значений конфигурации, которые будут возвращены на устройства конечных пользователей.

Firebase ML

Учетные данные, называемые токенами аутентификации при установке, используются Firebase ML для аутентификации устройств при взаимодействии с экземплярами приложений, например, для распространения моделей разработчиков в экземпляры приложений.

Хранилище сегментации пользователей Firebase

В хранилище сегментации пользователей Firebase хранятся идентификаторы установок Firebase , а также связанные с ними атрибуты и сегменты, чтобы предоставлять информацию для таргетинга другим сервисам Firebase, которые их используют.

Как правило, сервисы Firebase используют службу установки Firebase , не требуя от разработчиков прямого взаимодействия с API FIS. Однако бывают случаи, когда разработчикам приложений может потребоваться прямой вызов API FIS, например:

  • Чтобы удалить установку Firebase и связанные с ней данные.
  • Для получения идентификаторов (идентификаторов установок Firebase ) с целью выбора конкретных установок приложений.
  • Для получения токенов аутентификации при установке Firebase.

Для начала работы с прямым вызовом API FIS добавьте SDK в свое приложение.

Добавьте SDK для установки Firebase в ваше приложение.

iOS+

  1. Добавьте зависимость для установки Firebase в ваш Podfile:
    pod 'FirebaseInstallations'
  2. Выполните команду pod install и откройте созданный файл .xcworkspace .
  3. Импортируйте модуль FirebaseCore в ваш UIApplicationDelegate , а также любые другие модули Firebase, используемые вашим делегатом приложения. Например, чтобы использовать Cloud Firestore и Authentication :

    SwiftUI

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

    Быстрый

    import FirebaseCore
    import FirebaseFirestore
    import FirebaseAuth
    // ...
          

    Objective-C

    @import FirebaseCore;
    @import FirebaseFirestore;
    @import FirebaseAuth;
    // ...
          
  4. Настройте общий экземпляр FirebaseApp в методе application(_:didFinishLaunchingWithOptions:) вашего делегата приложения:

    SwiftUI

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

    Быстрый

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

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  5. Если вы используете SwiftUI, вам необходимо создать делегат приложения и прикрепить его к вашей структуре App с помощью UIApplicationDelegateAdaptor или NSApplicationDelegateAdaptor . Также необходимо отключить подмену делегатов приложения. Для получения дополнительной информации см. инструкции 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

Добавьте зависимость для установки Android SDK Firebase в файл Gradle вашего модуля (на уровне приложения) (обычно app/build.gradle ):

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

JavaScript

В зависимости от способа размещения вашего веб-приложения, конфигурация может обрабатываться автоматически, или вам может потребоваться обновить объект конфигурации Firebase .

Например, если ваши зависимости добавлены в index.html, добавьте зависимость в элемент <head>:

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

Порхание

  1. В корневом каталоге вашего Flutter-проекта выполните следующую команду для установки плагина Firebase installations:

    flutter pub add firebase_app_installations
    
  2. Перестройте свой проект:

    flutter run
    
  3. Импортируйте плагин для установки Firebase :

    import 'package:firebase_app_installations/firebase_app_installations.dart';
    

Удаление установки Firebase

Данные, связанные с установкой Firebase как правило, не содержат личной информации. Тем не менее, предоставление пользователям возможности управлять этими данными и удалять их может быть полезным.

Идентификаторы установки Firebase различаются для каждой установки каждого приложения; разные приложения на одном и том же устройстве имеют разные идентификаторы установки Firebase . Идентификаторы установки Firebase идентифицируют установки приложений и данные, связанные с этими установками приложений.

При удалении идентификатора установки данные, связанные с этим идентификатором, удаляются из рабочих и резервных систем всех сервисов Firebase, которые используют идентификаторы установок Firebase для идентификации установок, выполненных в течение последних 180 дней. Этот процесс в общих чертах описан в заявлении Google об удалении и хранении данных .

Если вы не отключите все службы генерации FID в своем приложении, FIS создаст новый идентификатор в течение нескольких дней. Firebase будет рассматривать вновь созданный идентификатор как новую установку Firebase и никак не свяжет его с предыдущим идентификатором или данными.

Удаление FID с помощью вызова API клиента

Для удаления FID, сгенерированных сервисами Firebase, вызовите соответствующий метод из SDK установки Firebase :

Быстрый

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

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

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

Удаление FID с помощью вызова API сервера.

Чтобы удалить FID с помощью вызова API сервера, добавьте Firebase Admin SDK на свой сервер , если вы еще этого не сделали.

После добавления SDK удаляйте FID, вызывая функцию удаления на выбранном вами языке программирования (примечание: за исключением Node.js, эти методы используют именование идентификаторов экземпляров. Однако все они фактически удаляют FID при вызове с любым текущим SDK Firebase).

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)

Идти

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

При удалении идентификатора установки Firebase с помощью вызова API сервера, сервисы Firebase запускают процесс удаления данных, связанных с этим идентификатором установки, прекращают прием новых данных для этого идентификатора в течение 1-2 дней, а затем уведомляют клиентское приложение об удалении идентификатора. До тех пор, пока Firebase не уведомит клиентское приложение, некоторые сервисы приложения могут по-прежнему использовать этот идентификатор — например, установка Firebase может продолжать получать уведомления FCM в течение нескольких часов.

Если вы хотите удалить текущий идентификатор установки Firebase и сразу же использовать сервисы Firebase с новым, не связанным с ней идентификатором, воспользуйтесь клиентским API для обработки удаления.

Получение идентификаторов клиента

Если вам необходимо идентифицировать конкретные установки вашего приложения, вы можете сделать это, получив идентификатор установки Firebase . Например, для создания сегментов установок приложения для импорта в BiqQuery или для проведения тестирования в процессе разработки Firebase In-App Messaging , вы можете идентифицировать и выбрать нужные устройства, используя соответствующие идентификаторы установок Firebase .

Чтобы получить идентификатор установки Firebase :

Быстрый

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

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

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

Получить токены аутентификации при установке

Сервисы Firebase могут аутентифицировать установки Firebase с помощью токенов аутентификации, полученных из FIS. Например, при разработке A/B-тестов для Remote Config вы можете аутентифицировать целевое тестовое устройство, используя токен аутентификации установки.

Токен авторизации установки — это кратковременный токен носителя в формате JSON Web Token (JWT), содержащий следующую информацию об установке:

  • Идентификатор установки Firebase
  • Соответствующий проект ( projectNumber )
  • Соответствующий идентификатор приложения Firebase ( appId )
  • Срок действия токена

Токен авторизации при установке не может быть отозван и остается действительным до истечения срока его действия. Срок действия токена по умолчанию составляет одну неделю.

Чтобы получить токен авторизации установки:

Быстрый

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

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

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

Отслеживайте жизненный цикл идентификаторов установки Firebase

В процессе обычной работы приложения идентификаторы установки Firebase (FID) не требуют специального мониторинга. Однако приложения, которые явно получают и используют FID, должны добавить логику для отслеживания возможного удаления или смены FID. Вот несколько случаев, когда FID могут быть удалены или сменены:

  • Удаление или повторная установка приложения, например, при установке пользователем на новое устройство.
  • Конечный пользователь очищает кэш приложения или устройства.
  • Удаление FID запускается на серверной части при отсутствии активности в приложении (в настоящее время пороговое значение составляет 270 дней бездействия).

В подобных случаях, когда приложения подвергаются ротации или удалению FID, им присваивается новый FID. Кроме того, токен авторизации установки, связанный с удаленным FID, удаляется независимо от срока его действия и заменяется новым токеном авторизации установки.

Приложения могут отслеживать эти изменения и реагировать соответствующим образом.

Для контроля вращения FID:

Быстрый

installationIDObserver = NotificationCenter.default.addObserver(
        forName: .InstallationIDDidChange,
        object: nil,
        queue: nil
) { (notification) in
  // Fetch new Installation ID
  Task {
    await 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];
}];

При каждом назначении нового FID в центр уведомлений NSNotificationCenter по умолчанию отправляется уведомление NSNotificationName.InstallationIDDidChange .

Android

Клиентам на Kotlin и Java следует добавить логику повторных попыток для обработки неудачных вызовов при получении нового FID.

JavaScript

Веб-приложения могут подписываться на обработчик onIdChange .

При каждом создании нового FID срабатывает подписанная функция обратного вызова:

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

Dart

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

Перенос данных с Instance ID на установки Firebase

До появления функции установки Firebase использовал SDK Instance ID для идентификации установленных приложений. Функция установки Firebase предоставляет значительные преимущества по сравнению с Instance ID в плане надежности, производительности и безопасности. Приложения Firebase, зависящие от SDK Instance ID, должны перейти на функцию установки Firebase .

Процесс миграции различается в зависимости от вашего приложения:

  • Приложения, которые не используют API идентификаторов экземпляров напрямую, могут перейти на Firebase, обновив версии своих SDK . Большинство приложений Firebase попадают в эту категорию.

  • Приложениям, которые явно обращаются к API-интерфейсу Instance ID, необходимо обновить версии SDK и внести изменения в код , заменив методы Instance ID на аналогичные методы из Firebase или FCM . Если ваше приложение использует Instance ID для получения токенов регистрации FCM , явно использует Instance ID для выбора экземпляров приложения или для любых других целей, вам потребуется обновить код приложения.

В настоящее время FIS обратно совместим с устаревшим идентификатором Firebase Instance ID. Удаление IID является альтернативным методом запроса на удаление данных с помощью этих SDK Firebase:

  • iOS 6.14.0 и ниже
  • Android SDK, выпущенные до 27 февраля 2020 года.

Это означает, что приложениям не обязательно переходить на установку Firebase ; однако, настоятельно рекомендуется это сделать.

Обновление до минимальных версий SDK для установок Firebase

Для перехода с Instance ID на установки Firebase убедитесь, что ваши приложения используют как минимум указанные минимальные версии следующих SDK Firebase:

Firebase SDK Минимальная версия Android Минимальная версия iOS
Firebase Cloud Messaging v20.3.0 v6.34.0
Удалённая конфигурация v19.2.0 v6.24.0
Google Analytics для Firebase (SDK для измерения данных) v17.4.4 v6.18.0
Встроенные сообщения в приложении v19.0.7 v6.24.0
Мониторинг производительности v19.0.8 v6.21.0
Crashlytics v17.2.1 v6.23.0
Набор ML v22.1.2 v6.28.0

Обновление кода, который явно вызывает API идентификаторов экземпляров.

Если ваше приложение для Android или Apple напрямую использует методы SDK идентификаторов экземпляров, вы можете заменить их идентичными альтернативами в SDK для установки Firebase или SDK FCM .

Получение идентификатора

Методы для получения идентификаторов экземпляров заменены методами для получения идентификатора установки. Например:

До

Быстрый

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

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];
    // display message
    NSLog(@"%@", 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

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

После

Быстрый

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

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

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

Удаление идентификатора

Методы удаления идентификаторов экземпляров заменены методами удаления идентификаторов установок Firebase . Например:

До

Быстрый

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

После

Быстрый

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

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

Получение регистрационного токена FCM

До появления функции Firebase Installations клиенты FCM получали токены регистрации из идентификатора экземпляра. Теперь SDK FCM предоставляет методы для получения токена регистрации.

До

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

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

Быстрый

InstanceID.instanceID().instanceID { result, error in
  if let error = error {
    print("Error fetching instance ID: \(error)")
  } else if let result = result {
    print("Instance ID token: \(result.token)")
  }
}

Objective-C

[[FIRInstanceID instanceID] instanceIDWithHandler:^(FIRInstanceIDResult * _Nullable result,
                                                    NSError * _Nullable error) {
  if (error != nil) {
    NSLog(@"Error fetching instance ID: %@", error);
  } else {
    NSLog(@"Instance ID token: %@", result.token);
  }
}];

После

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

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

Быстрый

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

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];
    // display message
    NSLog(@"%@", message);
  }
}];