Usando o acionamento da função em segundo plano do Remote Config fornecido pelo Cloud Functions para Firebase junto com o FCM , você pode propagar as atualizações do Remote Config em tempo real. Neste cenário, você cria uma função que é acionada quando você publica ou reverte seu modelo de configuração remota do painel ou da API. A atualização do modelo aciona a função para enviar uma mensagem FCM para permitir que os clientes saibam que sua configuração existente está obsoleta e que sua próxima busca deve ser do servidor:
O restante deste documento orienta você por essas etapas para propagar as atualizações do Remote Config em tempo real.
Inscrever instâncias de aplicativo cliente em um tópico do FCM
Para direcionar uma mensagem FCM para um grande grupo de instâncias de aplicativo cliente, como toda a sua base de usuários, o sistema de mensagens de tópico é o mecanismo mais eficiente. Cada instância de aplicativo que deve receber atualizações de configuração remota em tempo real deve se inscrever em um nome de tópico como, por exemplo, PUSH_RC
:
Rápido
extension AppDelegate : MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { messaging.subscribe(toTopic: "PUSH_RC") { error in print("Subscribed to PUSH_RC topic") } } }
Objective-C
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { [[FIRMessaging messaging] subscribeToTopic:@"PUSH_RC" completion:^(NSError * _Nullable error) { NSLog(@"Subscribed to PUSH_RC topic"); }]; }
Android
@Override public void onNewToken(String s) { FirebaseMessaging.getInstance().subscribeToTopic("PUSH_RC"); }
Crie uma função para enviar um ping do FCM nas atualizações do modelo
Você pode acionar uma função em resposta a eventos de configuração remota, incluindo a publicação de uma nova versão de configuração ou a reversão para uma versão mais antiga. Para propagar atualizações de modelo em tempo real, crie uma função que detecte eventos de publicação de modelo e, em seguida, use o FCM Admin SDK de sua função para enviar um ping silencioso para instâncias de aplicativo cliente:
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; }); });
Esta função define um parâmetro CONFIG_STATE
e, em seguida, envia-o como carga útil de dados de uma mensagem FCM para todos os clientes inscritos no tópico PUSH_RC
.
Definir o estado do Remote Config no cliente
A carga útil de dados mostrada na etapa anterior sempre define CONFIG_STATE
como STALE
nas preferências compartilhadas do aplicativo. Isso indica que o modelo do Remote Config já armazenado no aplicativo agora está obsoleto devido à criação do novo modelo atualizado cuja publicação acionou a função. Atualize seu gerenciador de notificação para testar esta condição:
Rápido
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) }
Objective-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); }
Android
@Override public void onMessageReceived(RemoteMessage remoteMessage) { if (remoteMessage.getData().containsKey("CONFIG_STATE")) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); sharedPreferences.edit().putBoolean("CONFIG_STALE", true).apply(); } }
Busque as atualizações do Remote Config na inicialização do aplicativo
Rápido
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() } }
Objective-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]; }]; }
Android
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")); } }); }
Por fim, adicione lógica ao seu aplicativo para forçar uma busca de configuração remota da rede (ignorando o armazenamento local) porque CONFIG_STATE
é STALE
. Se seu aplicativo busca na rede com muita frequência, pode ser limitado pelo Firebase. Consulte Limitação .