FCM 과 함께 Firebase용 Cloud Functions에서 제공하는 원격 구성 백그라운드 함수 트리거를 사용하여 원격 구성 업데이트를 실시간으로 전파할 수 있습니다. 이 시나리오에서는 대시보드 또는 API에서 원격 구성 템플릿을 게시하거나 롤백할 때 트리거되는 함수를 만듭니다. 템플릿 업데이트는 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 ping을 보내는 함수 만들기
새 구성 버전의 게시 또는 이전 버전으로의 롤백을 포함하여 원격 구성 이벤트에 대한 응답으로 기능을 트리거할 수 있습니다. 템플릿 업데이트를 실시간으로 전파하려면 템플릿 게시 이벤트를 수신하는 함수를 만든 다음 함수에서 FCM Admin SDK를 사용하여 클라이언트 앱 인스턴스에 자동 ping을 보냅니다.
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_STATE
를 STALE
로 설정합니다. 이는 앱에 이미 저장된 원격 구성 템플릿이 해당 게시가 함수를 트리거한 업데이트된 새 템플릿의 생성으로 인해 부실함을 나타냅니다. 이 조건을 테스트하려면 알림 핸들러를 업데이트하십시오.
빠른
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_STATE
가 STALE
이기 때문에 네트워크에서 원격 구성을 강제로 가져오도록(로컬 저장소 무시) 로직을 앱에 추가합니다. 앱이 네트워크에서 너무 자주 가져오는 경우 Firebase에 의해 제한될 수 있습니다. 스로틀링 을 참조하십시오.