Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

원격 구성 업데이트를 실시간으로 전파

FCM 과 함께 Firebase용 Cloud Functions에서 제공하는 원격 구성 백그라운드 기능 트리거를 사용하여 원격 구성 업데이트를 실시간으로 전파할 수 있습니다. 이 시나리오에서는 대시보드 또는 API에서 원격 구성 템플릿을 게시하거나 롤백할 때 트리거되는 함수를 만듭니다. 템플릿 업데이트는 FCM 메시지를 보내는 기능을 트리거하여 클라이언트에게 기존 구성이 오래되었고 다음 가져오기가 서버에서 이루어져야 함을 알립니다.

Cloud Functions를 통해 FCM 알림을 트리거하는 원격 구성 업데이트를 보여주는 다이어그램

이 문서의 나머지 부분에서는 원격 구성 업데이트를 실시간으로 전파하는 이러한 단계를 안내합니다.

FCM 주제에 대한 클라이언트 앱 인스턴스 구독

전체 사용자 기반과 같은 대규모 클라이언트 앱 인스턴스 그룹에 FCM 메시지를 대상으로 하는 경우 주제 메시징이 가장 효율적인 메커니즘입니다. 실시간 원격 구성 업데이트를 수신해야 하는 각 앱 인스턴스는 PUSH_RC 와 같은 주제 이름을 구독해야 합니다.

빠른

extension AppDelegate : MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        messaging.subscribe(toTopic: "PUSH_RC") { error in
            print("Subscribed to PUSH_RC topic")
        }
    }
}
    

오브젝티브-C

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    [[FIRMessaging messaging] subscribeToTopic:@"PUSH_RC" completion:^(NSError * _Nullable error) {
        NSLog(@"Subscribed to PUSH_RC topic");
    }];
}
    

기계적 인조 인간

@Override
public void onNewToken(String s) {
    FirebaseMessaging.getInstance().subscribeToTopic("PUSH_RC");
}
    

템플릿 업데이트 시 FCM 핑을 보내는 함수 만들기

새 구성 버전 게시 또는 이전 버전으로의 롤백을 포함하여 원격 구성 이벤트에 대한 응답으로 기능을 트리거할 수 있습니다. 템플릿 업데이트를 실시간으로 전파하려면 템플릿 게시 이벤트를 수신하는 함수를 만든 다음 함수에서 FCM Admin SDK를 사용하여 클라이언트 앱 인스턴스에 자동 핑을 보냅니다.

exports.pushConfig = functions.remoteConfig.onUpdate(versionMetadata => {
  // Create FCM payload to send data message to PUSH_RC topic.
  const payload = {
    topic: "PUSH_RC",
    data: {
      "CONFIG_STATE": "STALE"
    }
  };
  // Use the Admin SDK to send the ping via FCM.
  return admin.messaging().send(payload).then(resp => {
    console.log(resp);
    return null;
  });
});

이 함수는 CONFIG_STATE 매개변수를 설정한 다음 PUSH_RC 주제를 구독하는 모든 클라이언트에 FCM 메시지의 데이터 페이로드로 전송합니다.

클라이언트에서 원격 구성 상태 설정

이전 단계에 표시된 데이터 페이로드는 앱의 공유 기본 설정에서 항상 CONFIG_STATESTALE 로 설정합니다. 이는 게시로 인해 기능이 트리거된 업데이트된 새 템플릿이 생성되어 앱에 이미 저장된 원격 구성 템플릿이 이제 부실함을 나타냅니다. 이 조건을 테스트하려면 알림 핸들러를 업데이트하세요.

빠른

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    if (userInfo.index(forKey: "CONFIG_STATE") != nil) {
        print("Config set to stale")
        UserDefaults.standard.set(true, forKey:"CONFIG_STALE")
    }

    completionHandler(UIBackgroundFetchResult.newData)
}
    

오브젝티브-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    if (userInfo[@"CONFIG_STATE"]) {
        NSLog(@"Config set to stale");
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"CONFIG_STALE"];
    }

    completionHandler(UIBackgroundFetchResultNewData);
}
    

기계적 인조 인간

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (remoteMessage.getData().containsKey("CONFIG_STATE")) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.edit().putBoolean("CONFIG_STALE", true).apply();
    }
}
    

앱 시작 시 원격 구성 업데이트 가져오기

빠른

func fetchConfig() {
  welcomeLabel.text = remoteConfig[loadingPhraseConfigKey].stringValue

  var expirationDuration = 3600
  // If your app is using developer mode, expirationDuration is set to 0, so each fetch will
  // retrieve values from the service.
  if remoteConfig.configSettings.isDeveloperModeEnabled || UserDefaults.standard.bool(forKey: "CONFIG_STALE") {
    expirationDuration = 0
  }

  remoteConfig.fetch(withExpirationDuration: TimeInterval(expirationDuration)) { (status, error) -> Void in
    if status == .success {
      print("Config fetched!")
      self.remoteConfig.activateFetched()
    } else {
      print("Config not fetched")
      print("Error: \(error?.localizedDescription ?? "No error available.")")
    }
    self.displayWelcome()
  }
}
    

오브젝티브-C

- (void)fetchConfig {
    self.welcomeLabel.text = self.remoteConfig[kLoadingPhraseConfigKey].stringValue;

    long expirationDuration = 3600;
    // If your app is using developer mode, expirationDuration is set to 0, so each fetch will
    // retrieve values from the Remote Config service.
    if (self.remoteConfig.configSettings.isDeveloperModeEnabled || [[NSUserDefaults standardUserDefaults] boolForKey:@"CONFIG_STALE"]) {
        expirationDuration = 0;
    }

    [self.remoteConfig fetchWithExpirationDuration:expirationDuration completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
        if (status == FIRRemoteConfigFetchStatusSuccess) {
            NSLog(@"Config fetched!");
            [self.remoteConfig activateFetched];
            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"CONFIG_STALE"];
        } else {
            NSLog(@"Config not fetched");
            NSLog(@"Error %@", error.localizedDescription);
        }
        [self displayWelcome];
    }];
}
    

기계적 인조 인간

private void fetchWelcomeMessage() {
    mWelcomeTextView.setText(mFirebaseRemoteConfig.getString("loading_phrase"));

    long cacheExpiration = 43200; // 12 hours in seconds.
    // If your app is using developer mode or cache is stale, cacheExpiration is set to 0,
    // so each fetch will retrieve values from the service.
    if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled() ||
            mSharedPreferences.getBoolean("CONFIG_STALE", false)) {
        cacheExpiration = 0;
    }

    mFirebaseRemoteConfig.fetch(cacheExpiration)
            .addOnCompleteListener(this, new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Toast.makeText(MainActivity.this, "Fetch Succeeded",
                                Toast.LENGTH_SHORT).show();

                        // After config data is successfully fetched, it must be activated before newly fetched
                        // values are returned.
                        mFirebaseRemoteConfig.activateFetched();
                    } else {
                        Toast.makeText(MainActivity.this, "Fetch Failed",
                                Toast.LENGTH_SHORT).show();
                    }
                    mWelcomeTextView.setText(mFirebaseRemoteConfig.getString("welcome_message"));
                }
            });
}
    

마지막으로 CONFIG_STATESTALE 이기 때문에 네트워크에서 원격 구성을 강제로 가져오는 논리를 앱에 추가합니다(로컬 저장소 무시). 앱이 네트워크에서 너무 자주 가져오면 Firebase에 의해 제한될 수 있습니다. 조절 을 참조하십시오.