FCM 등록 토큰 관리를 위한 권장사항

FCM API를 사용하여 전송 요청을 프로그래매틱 방식으로 빌드하는 경우 시간이 지나면서 메일을 비활성 상태로 보내면 리소스가 낭비되고 있음을 확인할 수 있습니다. 비활성 등록 토큰이 있는 기기 이 상황은 메일에 영향을 줄 수 있습니다. Firebase Console에 보고된 전송 데이터 또는 BigQuery로 내보낸 데이터 실질적으로는 그렇지 않은 게재율의 급격한 감소로 나타납니다. 이 이 가이드에서는 효율적인 메시지를 보장하기 위해 취할 수 있는 몇 가지 조치를 설명합니다. 타겟팅 및 유효한 게재 보고

비활성 및 만료된 등록 토큰

비활성 등록 토큰은 FCM에 1개월 이상 연결되지 않았습니다. 시간이 지나면서 기기가 FCM에 다시 연결될 가능성도 낮습니다. 메시지 이러한 비활성 토큰에 대한 주제 팬아웃은 합니다.

토큰이 비활성 상태가 되는 데에는 몇 가지 이유가 있습니다. 예를 들어 토큰이 손실되거나, 폐기되거나, 스토리지로 넘어가거나, 잊어버렸죠.

비활성 토큰이 270일 동안 비활성 상태가 되면 FCM에서 이를 고려합니다. 만료된 토큰. 토큰이 만료되면 FCM는 토큰을 잘못된 것으로 표시하고 반환합니다. 하지만 FCM는 앱의 새 토큰을 발급합니다. 인스턴스가 다시 연결되고 앱이 열리는 경우도 있습니다.

기본 권장사항

API를 사용하는 모든 앱에서 따라야 하는 몇 가지 FCM API: 전송 요청을 프로그래매틱 방식으로 빌드합니다. 기본 인기 관행은 다음과 같습니다.

  • FCM에서 등록 토큰을 가져와 있습니다. 서버의 중요한 역할은 각 클라이언트의 활성 토큰의 업데이트된 목록을 유지합니다. 다음을 적극 권장합니다. 코드 및 서버에 토큰 타임스탬프를 구현하고 정기적으로 이 타임스탬프를 업데이트합니다.
  • 토큰 최신성을 유지하고 비활성화된 토큰을 삭제합니다. 또한 FCM에서 더 이상 유효하지 않은 토큰을 삭제하는 경우 토큰�� 비활성 상태가 된 다른 징후를 모니터링하고 삭제합니다 있습니다 이 가이드에서는 이를 위한 몇 가지 옵션을 설명합니다.

등록 토큰 검색 및 저장

앱을 처음 시작할 때 FCM SDK에서 등록을 생성합니다. 클라이언트 앱 인스턴스의 토큰입니다. 이 토큰은 API에서 타겟팅된 전송 요청을 전송하거나 타겟팅을 위해 주제 구독에 추가합니다. 참조하세요

앱은 처음 시작할 때 이 토큰을 가져와서 저장하는 것이 좋습니다. 타임스탬프와 함께 앱 서버에 전달합니다. 타임스탬프는 직접 구현하지 않아도 되므로 FCM SDK

또한 토큰을 서버에 저장하고 타임스탬프의 다음과 같이 변경될 때마다:

  • 새 기기에서 앱 복원
  • 사용자가 앱 제거 또는 재설치
  • 사용자가 앱 데이터 삭제
  • FCM가 기존 앱을 만료한 후에 앱이 다시 활성화됩니다. 토큰

예: Cloud Firestore에 토큰과 타임스탬프를 저장하세요.

예를 들어 Cloud Firestore를 사용하여 fcmTokens라는 컬렉션에 토큰을 저장할 수 있습니다. 컬렉션의 각 문서 ID는 문서에 현재 등록 토큰과 최종 업데이트된 타임스탬프 다음 Kotlin 예와 같이 set 함수를 사용합니다.

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private fun sendTokenToServer(token: String?) {
        // If you're running your own server, call API to send token and today's date for the user

        // Example shown below with Firestore
        // Add token and timestamp to Firestore for this user
        val deviceToken = hashMapOf(
            "token" to token,
            "timestamp" to FieldValue.serverTimestamp(),
        )
        // Get user ID from Firebase Auth or your own server
        Firebase.firestore.collection("fcmTokens").document("myuserid")
            .set(deviceToken)
    }

토큰이 검색될 때마다 다음을 호출하여 Cloud Firestore에 저장됩니다. sendTokenToServer:

    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // FCM registration token to your app server.
        sendTokenToServer(token)
    }
        var token = Firebase.messaging.token.await()

        // Check whether the retrieved token matches the one on your server for this user's device
        val preferences = this.getPreferences(Context.MODE_PRIVATE)
        val tokenStored = preferences.getString("deviceToken", "")
        lifecycleScope.launch {
            if (tokenStored == "" || tokenStored != token)
            {
                // If you have your own server, call API to send the above token and Date() for this user's device

                // Example shown below with Firestore
                // Add token and timestamp to Firestore for this user
                val deviceToken = hashMapOf(
                    "token" to token,
                    "timestamp" to FieldValue.serverTimestamp(),
                )

                // Get user ID from Firebase Auth or your own server
                Firebase.firestore.collection("fcmTokens").document("myuserid")
                    .set(deviceToken).await()
            }
        }

토큰 최신 상태 유지 및 비활성 토큰 삭제

토큰이 최신 상태인지 비활성 상태인지를 판단하는 것이 항상 간단하지만은 않습니다. 받는사람 모든 경우에 적용할 수 있으므로, 토큰을 고려하고 있는 경우에 대한 임곗값을 채택해야 합니다 오래됨 기본적으로 FCM는 앱이 있는 경우 토큰을 비활성으로 간주합니다. 인스턴스가 한 달 동안 연결되지 않았습니다. 1개월보다 오래된 토큰은 비활성화된 기기가 될 수 있습니다. 활성 기기가 아니었다면 토큰입니다.

사용 사례에 따라 한 달이 너무 짧거나 너무 길어질 수 있으므로 귀사에 적합한 기준을 결정할 수 있습니다.

FCM 백엔드에서 잘못된 토큰 응답 감지

FCM에서 잘못된 토큰 응답을 감지하고 다음과 같이 응답해야 합니다. 유효하지 않은 것으로 알려진 등록 토큰을 시스템에서 삭제 또는 만료된 경우. HTTP v1 API를 사용하는 경우 이러한 오류 메시지는 다음을 나타낼 수 있습니다. 전송 요청이 잘못되거나 만료된 토큰을 타겟팅했습니다.

  • UNREGISTERED(HTTP 404)
  • INVALID_ARGUMENT(HTTP 400)

메시지 페이로드가 유효하고 대상 토큰에 대해 이 응답을 받지 않는 경우 이 기록의 기록을 삭제하는 것이 안전합니다. 다시는 유효하지 않으므로 예를 들어 유효하지 않은 토큰을 삭제하고 Cloud Firestore에서 다음과 같은 함수를 배포하고 실행할 수 있습니다.

    // Registration token comes from the client FCM SDKs
    const registrationToken = 'YOUR_REGISTRATION_TOKEN';

    const message = {
    data: {
        // Information you want to send inside of notification
    },
    token: registrationToken
    };

    // Send message to device with provided registration token
    getMessaging().send(message)
    .then((response) => {
        // Response is a message ID string.
    })
    .catch((error) => {
        // Delete token for user if error code is UNREGISTERED or INVALID_ARGUMENT.
        if (errorCode == "messaging/registration-token-not-registered") {
            // If you're running your own server, call API to delete the
            token for the user

            // Example shown below with Firestore
            // Get user ID from Firebase Auth or your own server
            Firebase.firestore.collection("fcmTokens").document(user.uid).delete()
        }
    });

FCM는 토큰이 만료된 경우에만 잘못된 토큰 응답을 반환합니다. 270일이 경과하거나 클라이언트가 명시적으로 등록을 취소한 경우. 더 많은 자체 정의에 따라 비활성을 정확하게 추적하고 사전에 비활성 등록 토큰을 삭제합니다.

정기적으로 토큰 업데이트

서버에서 모든 등록 토큰을 주기적으로 검색 및 업데이트하는 것이 좋습니다. 이를 위해 다음을 수행해야 합니다.

  • 클라이언트 앱에 앱 로직을 추가하여 적절한 API 호출 (예: token(completion): 드림 Apple 플랫폼용 또는 getToken() 현재 토큰을 앱 서버로 전송하여 저장합니다. (타임스탬프 포함) 이 작업은 월별로 모든 작업을 클라이언트 또는 토큰을 사용합니다
  • 서버 로직을 추가하여 토큰의 타임스탬프를 일���한 간격으로 업데이트합니다. 토큰의 변경 여부와 관계없이

다음을 사용하여 토큰을 업데이트하는 Android 로직의 예는 다음과 같습니다. WorkManager 보기 클라우드 메시징 토큰 관리 참조하세요.

어떤 타이밍 패턴을 따르든 토큰을 주기적으로 업데이트해야 합니다. 한 달에 한 번 업데이트 빈도를 적절하게 조정하여 배터리에 미치는 영향 간에 적절한 균형을 유지합니다. 비활성 등록 토큰 감지에 대해 다룹니다. 이 새로고침을 수행하면 비활성화 된 모든 장치가 활성화 될 때 등록을 새로 고치도록 다시 활성화됩니다. 새로고침을 더 자주 해도 효과가 없습니다. 더 높습니다.

비활성 등록 토큰 삭제

기기에 메시지를 보내기 전에 기기의 타임스탬프가 등록 토큰이 비활성 기간 내에 있어야 합니다. 예를 들어 Cloud Functions for Firebase를 구현하여 일일 검사를 실행하여 타임스탬프가 const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;와 같이 정의된 비활성 기간 내에 있는지 확인한 후 비활성 토큰을 삭제할 수 있습니다.

exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
  // Get all documents where the timestamp exceeds is not within the past month
  const staleTokensResult = await admin.firestore().collection('fcmTokens')
      .where("timestamp", "<", Date.now() - EXPIRATION_TIME)
      .get();
  // Delete devices with stale tokens
  staleTokensResult.forEach(function(doc) { doc.ref.delete(); });
});

주제에서 비활성 토큰 구독 취소

주제를 사용하는 경우 주제에서 비활성 토큰의 등록을 취소할 수도 있습니다. 확인할 수 있습니다 여기에는 두 단계가 포함됩니다.

  1. 앱은 한 달에 한 번, 그리고 정기 결제가 이루어질 때마다 등록 토큰이 변경됩니다. 이것은 자가 치유 솔루션을 형성합니다. 앱이 다시 활성화되면 정기 결제 항목이 자동으로 다시 표시됩니다.
  2. 앱 인스턴스가 한 달 동안 (또는 자체 비활성 기간) 유휴 상태인 경우 구독 취소하려는 경우 Firebase Admin SDK를 사용해 FCM 백엔드에서 주제 매핑 토큰을 삭제합니다.

이러한 두 단계의 장점은 팬아웃할 비활성 토큰이 적기 때문에 팬아웃이 더 빨리 일어나고, 비활성 앱 인스턴스는 다시 활성 상태가 되었을 때 자동으로 재구독된다는 것입니다.

게재 성공 측정

메시지 전송을 가장 정확하게 파악하려면 활발히 사용되는 앱 인스턴스에 메시지를 보낼 수 있습니다 이는 특히 구독자가 많은 주제에 정기적으로 메시지를 보내는 행위 만약 이러한 구독자 중 일부가 실제로 비활성 상태이므로 게재에 미치는 영향은 시간이 지남에 따라 크게 달라질 수 있습니다.

메시지를 토큰으로 타겟팅하기 전에 다음을 고려하세요.

  • Google 애널리틱스, BigQuery에서 캡처한 데이터 또는 기타 추적 신호를 수행합니다. 토큰이 활성 상태임을 나타내나요?
  • 일정 기간 동안 이전 전송 시도가 지속적으로 실패했나요?
  • 지난달에 서버에서 등록 토큰이 업데이트되었나요?
  • Android 기기의 경우 FCM Data API가 실행되나요? HTTP(S) 부하 분산기로 인한 메시지 전송 실패의 droppedDeviceInactive을(를) 삭제하시겠습니까?

전송에 대한 자세한 내용은 메시지 전송 이해를 참조하세요.