Catch up on everything we announced at this year's Firebase Summit. Learn more

Firebase 설치 관리

Firebase 설치 서비스(FIS)는 Firebase 앱의 설치된 각 인스턴스에 Firebase 설치 ID(FID)를 제공합니다. Firebase 설치 ID는 다음 Firebase 서비스에서 내부적으로 사용됩니다.

Firebase 서비스 Firebase 설치 기능
Firebase 클라우드 메시징

Firebase 클라우드 메시징은 Firebase 설치 ID를 사용하여 메시지 전송을 위한 기기를 타겟팅합니다.

Firebase 인앱 메시지

Firebase 인앱 메시지는 Firebase 설치 ID를 사용하여 메시지 전송을 위한 기기를 타겟팅합니다.

Firebase Performance Monitoring

Performance Monitoring은 Firebase 설치 ID를 사용하여 네트워크 리소스에 액세스하는 고유한 Firebase 설치 수를 계산하여 액세스 패턴이 충분히 익명 처리되도록 합니다. 또한 Firebase 원격 구성과 함께 Firebase 설치 ID를 사용하여 성능 이벤트 보고의 비율을 관리합니다.

Firebase 예측

예측은 Firebase 설치 ID를 사용하여 Firebase 설치를 프로젝트와 연결하고 시계열 이벤트를 검색합니다. 이러한 이벤트를 사용하여 고객이 지정한 이벤트의 발생 가능성을 예측할 뿐만 아니라 기본적으로 비용 예측 및 앱 제거 예측도 수행합니다.

Firebase용 Google 애널리틱스

Firebase용 Google 애널리틱스는 데이터를 사용하여 분석 및 기여 분석 정보를 제공합니다. 수집된 정보의 정확성은 기기와 환경에 따라 달라집니다.

Firebase 원격 구성

원격 구성은 Firebase 설치 ID를 사용하여 최종 사용자 기기로 반환할 구성 값을 선택합니다.

Firebase ML

설치 인증 토큰이라는 사용자 인증 정보는 Firebase ML이 앱 인스턴스와 상호작용(예: 개발자 모델을 앱 인스턴스에 배포)할 때 기기 인증을 위해 사용합니다.

일반적으로 Firebase 서비스는 Firebase 설치 서비스를 사용하여 개발자가 FIS API와 직접 상호작용할 필요가 없습니다. 하지만 앱 개발자가 다음과 같이 FIS API를 직접 호출해야 할 경우도 있습니다.

  • 설치에 연결된 Firebase 설치 및 데이터 삭제
  • 특정 앱 설치를 타겟팅하기 위해 식별자(Firebase 설치 ID) 검색
  • Firebase 설치를 인증하기 위해 설치 인증 토큰 검색

FIS API를 직접 호출하여 시작하려면 앱에 SDK를 추가하세요.

앱에 Firebase 설치 SDK 추가

iOS+

  1. Podfile에 Firebase 설치 종속 항목을 추가합니다.
    pod 'Firebase/Installations'
  2. pod install을 실행하고 생성된 .xcworkspace 파일을 엽니다.
  3. UIApplicationDelegate에서 Firebase 모듈을 가져옵니다.

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. 일반적으로 앱의 application:didFinishLaunchingWithOptions: 메서드에서 FirebaseApp 공유 인스턴스를 구성합니다.

    Swift

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

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];

Android

다음과 같이 모듈(앱 수준) Gradle 파일(일반적으로 app/build.gradle)에 Firebase 설치 Android SDK 종속 항목을 추가합니다.

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

자바스크립트

웹 애플리케이션의 호스팅 방식에 따라 구성이 자동으로 처리되거나 Firebase 구성 객체를 업데이트해야 할 수 있습니다.

예를 들어 종속 항목이 index.html에 추가된 경우 <head> 요소에 해당 종속 항목을 추가합니다.

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

Firebase 설치 삭제

Firebase 설치와 연결된 데이터는 일반적으로 개인 식별 데이터가 아닙니다. 하지만 사용자에게 이러한 데이터를 관리하고 삭제할 수 있는 옵션을 제공하면 도움이 될 수 있습니다.

Firebase 설치 ID는 설치하는 애플리케이션마다 다릅니다. 동일한 기기에 설치된 애플리케이션마다 각각의 Firebase 설치 ID가 있습니다. Firebase 설치 ID는 앱 설치 및 해당 앱 설치에 연결된 데이터를 식별합니다.

설치 ID를 삭제하면 설치 ID와 연결된 데이터가 Firebase 설치 ID를 사용하여 설치를 식별하는 모든 Firebase 서비스의 라이브 및 백업 시스템에서 180일 이내에 삭제됩니다. 이 프로세스는 삭제 및 보관에 관한 Google 문서에 간단히 설명되어 있습니다.

앱에서 모든 FID 생성 서비스를 중지하지 않았다면 FIS에서 며칠 내에 새 ID를 생성합니다. Firebase는 새로 생성된 ID를 새로운 Firebase 설치로 간주하고 어떤 방식으로도 이전 ID 또는 데이터와 연결하지 않습니다.

클라이언트 API 호출로 FID 삭제

Firebase 서비스에서 생성된 FID를 삭제하려면 Firebase 설치 SDK에서 적절한 메서드를 호출합니다.

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

자바

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

자바스크립트

await firebase.installations().delete();

서버 API 호출로 FID 삭제

서버 API 호출로 FID를 삭제하려면 서버에 Firebase Admin SDK를 추가합니다(아직 추가하지 않은 경우).

SDK가 추가되었으면 원하는 언어로 삭제 함수를 호출하여 FID를 삭제합니다(참고: Node.js를 제외하고 이러한 메서드는 인스턴스 ID 이름을 반영하지만 현재 Firebase SDK로 호출되면 실제로는 FID를 삭제합니다).

Node.js

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

admin.installations().deleteInstallation(idToDelete);

자바

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

서버 API 호출로 Firebase 설치 ID를 삭제하면 Firebase 서비스가 해당 설치 ID에 연결된 데이터를 삭제하는 프로세스를 시작하고, 1~2일 동안 해당 ID에 새 데이터를 허용하지 않으며, 클라이언트 앱에 ID가 삭제되었다는 알림을 보냅니다. Firebase에서 클라이언트 앱에 알림을 보내기 전까지 일부 앱 서비스에서 해당 ID를 계속 타겟팅할 수 있습니다. 예를 들어 Firebase 설치가 몇 시간 동안 계속 FCM 알림을 받을 수 있습니다.

현재 Firebase 설치 ID를 삭제하고 관련 없는 새 ID로 Firebase 서비스를 즉시 사용하려면 클라이언트 API를 사용하여 삭제를 처리합니다.

클라이언트 식별자 가져오기

앱의 특정 설치를 식별해야 하는 경우 Firebase 설치 ID를 가져오면 됩니다. 예를 들어 Firebase 인앱 메시지 개발 중에 테스트를 수행하려면 Firebase 설치 ID를 사용하여 올바른 테스트 기기를 식별하고 타겟팅하면 됩니다.

Firebase 설치 ID를 가져오려면 다음 단계를 따르세요.

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

자바

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

자바스크립트

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

설치 인증 토큰 검색

Firebase 서비스는 FIS에서 검색한 인증 토큰을 사용하여 Firebase 설치를 인증할 수 있습니다. 예를 들어 원격 구성의 A/B 테스트를 설계할 때 설치 인증 토큰을 사용하여 타겟팅된 테스트 기기를 인증할 수 있습니다.

설치 인증 토큰은 JSON 웹 토큰(JWT) 형식의 단기 Bearer 토큰이며 다음과 같은 설치 정보를 포함합니다.

  • Firebase 설치 ID
  • 연결된 프로젝트(projectNumber)
  • 연결된 Firebase 애플리케이션 ID(appId)
  • 토큰의 만료일

설치 인증 토큰은 취소할 수 없으며 만료일까지 유효합니다. 토큰의 기본 수명은 1주일입니다.

설치 인증 토큰을 검색하려면 다음 안내를 따르세요.

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

자바

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

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

자바스크립트

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

Firebase 설치 ID 수명 주기 모니터링

앱이 정상적으로 작동하는 동안에는 Firebase 설치 ID(FID)에 특별한 모니터링이 필요하지 않습니다. 그러나 FID를 명시적으로 검색하고 사용하는 앱에서는 FID의 삭제 또는 순환 가능성을 모니터링하는 로직을 추가해야 합니다. 다음은 FID가 삭제되거나 순환될 수 있는 몇 가지 경우입니다.

  • 앱 제거 또는 재설치. 예를 들어 최종 사용자가 새 기기에 앱을 설치하는 경우가 해당합니다.
  • 최종 사용자가 앱 또는 기기의 캐시를 삭제합니다.
  • 앱 비활성 상태로 인해 백엔드에서 FID 삭제가 트리거됩니다(현재 임곗값은 270일 동안 비활성 상태임).

이러한 경우 앱에서 FID 순환 또는 삭제가 발생하면 새 FID가 할당됩니다. 또한 삭제된 FID와 연결된 설치 인증 토큰은 자체 성숙도와 관계없이 삭제되고 새로운 설치 인증 토큰으로 대체됩니다.

앱은 이러한 변경사항을 모니터링하고 이에 따라 대응할 수 있습니다.

FID 순환을 모니터링하려면 다음 단계를 따르세요.

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];
}];

새 FID가 할당될 때마다 NSNotificationName.InstallationIDDidChange라는 NSNotification이 기본 NSNotificationCenter에 게시됩니다.

Android

Kotlin 및 자바 클라이언트는 새 FID를 검색하기 위해 실패한 호출에 응답하는 재시도 로직을 추가해야 합니다.

자바스크립트

웹 앱은 onIdChange 후크를 구독할 수 있습니다.

새 FID가 생성될 때마다 구독된 콜백이 트리거됩니다.

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

인스턴스 ID에서 Firebase 설치로 마이그레이션

Firebase 설치를 도입하기 전에 Firebase는 앱 설치의 식별자에 인스턴스 ID SDK를 사용했습니다. Firebase 설치는 안정성, 성능, 보안 측면에서 인스턴스 ID에 비해 훨씬 많은 이점을 제공합니다. 인스턴스 ID SDK를 사용하는 Firebase 앱은 Firebase 설치로 마이그레이션해야 합니다.

마이그레이션 프로세스는 앱에 따라 다릅니다.

  • Instance ID API를 직접 호출하지 않는 앱은 SDK 버전을 업데이트하여 마이그레이션할 수 있습니다. 대부분의 Firebase 앱이 이러한 범주에 속합니다.

  • 인스턴스 ID에 대해 명시적으로 API 호출을 수행하는 앱은 SDK 버전을 업데이트하고 코드를 변경하여 인스턴스 ID 메서드를 Firebase 설치 또는 그에 해당하는 FCM으로 변경해야 합니다. 앱에서 FCM 등록 토큰을 검색하기 위해 인스턴스 ID를 사용하거나 앱 인스턴스를 타겟팅하거나 다른 용도로 인스턴스 ID를 명시적으로 사용하는 경우 애플리케이션 코드를 업데이트해야 합니다.

현재 FIS는 기존 식별자인 Firebase 인스턴스 ID와 역호환됩니다. IID 삭제는 다음 Firebase SDK로 데이터 삭제를 요청하는 또 다른 방법입니다.

  • iOS 6.14.0 이하
  • 2020년 2월 27일 이전의 Android SDK

즉, 앱을 Firebase 설치로 반드시 마이그레이션해야 하는 것은 아니지만 마이그레이션하는 것이 좋습니다.

Firebase 설치를 위한 최소 SDK 버전으로 업그레이드

인스턴스 ID에서 Firebase 설치로 마이그레이션하려면 애플리케이션에서 최소한 다음 Firebase SDK의 나열된 최소 버전 번호를 사용해야 합니다.

Firebase SDK 최소 Android 버전 최소 iOS 버전
Firebase 클라우드 메시징 v20.3.0 v6.34.0
원격 구성 v19.2.0 v6.24.0
Firebase용 Google 애널리틱스 \ (Measurement SDK) v17.4.4 v6.18.0
인앱 메시지 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

Instance ID API를 명시적으로 호출하는 코드 업데이트

Android 또는 Apple 앱에서 Instance ID SDK 메서드를 직접 사용하는 경우 Firebase 설치 SDK 또는 FCM SDK에서 동일한 방식으로 사용하도록 변경할 수 있습니다.

식별자 검색

인스턴스 ID를 가져오는 메서드가 설치 ID를 가져오는 메서드로 변경됩니다. 예를 들면 다음과 같습니다.

이전

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;
   }
 }];

자바

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

이후

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

자바

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

식별자 삭제

인스턴스 ID를 삭제하는 메서드가 Firebase 설치 ID를 삭제하는 메서드로 변경됩니다. 예를 들면 다음과 같습니다.

이전

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

이후

Swift

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

Objective-C

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

자바

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

FCM 등록 토큰 검색

Firebase 설치가 도입되기 전에 FCM 클라이언트는 인스턴스 ID에서 등록 토큰을 검색했습니다. 이제 FCM SDK가 등록 토큰을 검색하는 메서드를 제공합니다.

이전

자바

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;
   }
 }];

이후

자바

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;
  }
}];