Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

Распространение обновлений Remote Config в режиме реального времени

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Используя запуск фоновой функции Remote Config, предоставляемый Cloud Functions для Firebase вместе с FCM , вы можете распространять обновления Remote Config в режиме реального времени. В этом сценарии вы создаете функцию, которая срабатывает, когда вы публикуете или откатываете свой шаблон Remote Config с панели управления или API. Обновление шаблона запускает функцию для отправки сообщения FCM, чтобы сообщить клиентам, что их существующая конфигурация устарела и что их следующая выборка должна быть с сервера:

Диаграмма, показывающая, как обновление Remote Config запускает оповещения FCM через облачные функции

В оставшейся части этого документа описаны шаги по распространению обновлений Remote Config в режиме реального времени.

Подпишите экземпляры клиентского приложения на тему FCM

Для нацеливания сообщения FCM на большую группу экземпляров клиентских приложений, таких как вся ваша пользовательская база, обмен сообщениями по темам является наиболее эффективным механизмом. Каждый экземпляр приложения, который должен получать обновления Remote Config в реальном времени, должен подписаться на имя темы, например, 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 при обновлении шаблона.

Вы можете активировать функцию в ответ на события Remote Config, включая публикацию новой версии конфигурации или откат к более старой версии. Чтобы распространять обновления шаблонов в режиме реального времени, создайте функцию, которая отслеживает события публикации шаблона, а затем используйте SDK администратора FCM из своей функции, чтобы отправить пинг экземплярам клиентского приложения без вывода сообщений:

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 , а затем отправляет его в качестве полезных данных сообщения FCM всем клиентам, подписанным на тему PUSH_RC .

Установите состояние Remote Config на клиенте

Полезная нагрузка данных, показанная на предыдущем шаге, всегда устанавливает для CONFIG_STATE значение STALE в общих настройках приложения. Это указывает на то, что шаблон Remote Config, уже сохраненный в приложении, теперь устарел из-за создания нового обновленного шаблона, публикация которого активировала функцию. Обновите обработчик уведомлений, чтобы проверить это условие:

Быстрый

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

Получение обновлений Remote Config при запуске приложения

Быстрый

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

Наконец, добавьте в свое приложение логику для принудительной выборки Remote Config из сети (игнорируя локальное хранилище), поскольку CONFIG_STATE имеет STALE . Если ваше приложение слишком часто получает данные из сети, оно может быть ограничено Firebase. См. Дросселирование .