Menerapkan update Remote Config secara real time

Dengan menggunakan pemicuan fungsi latar belakang Remote Config yang disediakan oleh Cloud Functions for Firebase bersama dengan FCM, Anda dapat menerapkan update Remote Config secara real time. Dalam skenario ini, Anda membuat fungsi yang terpicu ketika Anda memublikasikan atau melakukan rollback template Remote Config dari dasbor atau API. Update template akan memicu fungsi untuk mengirim pesan FCM agar klien tahu bahwa konfigurasi yang ada sudah tidak berlaku dan bahwa pengambilan selanjutnya harus berasal dari server.

Diagram yang menunjukkan update Remote Config yang memicu pemberitahuan FCM melalui Cloud Functions

Bagian selanjutnya dari dokumen ini menuntun Anda melalui langkah-langkah ini untuk menerapkan update Remote Config secara real time.

Membuat instance aplikasi klien berlangganan topik FCM

Untuk menargetkan pesan FCM ke sekelompok besar instance aplikasi klien, misalnya seluruh basis pengguna Anda, pengiriman pesan topik adalah mekanisme yang paling efisien. Setiap instance aplikasi yang harus menerima update Remote Config secara real time harus berlangganan nama topik, misalnya, PUSH_RC:

Swift

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

Membuat fungsi untuk mengirim ping FCM saat terjadi update template

Anda dapat memicu fungsi sebagai respons terhadap peristiwa Remote Config, termasuk publikasi versi konfigurasi baru atau rollback ke versi yang lebih lama. Untuk menerapkan update template secara real time, buat fungsi yang mendeteksi peristiwa publikasi template, lalu gunakan FCM Admin SDK dari fungsi Anda untuk mengirim ping senyap ke instance aplikasi klien:

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

Fungsi ini menetapkan parameter CONFIG_STATE, kemudian mengirimkannya sebagai payload data dari pesan FCM ke semua klien yang berlangganan topik PUSH_RC.

Menetapkan status Remote Config pada klien

Payload data yang ditunjukkan pada langkah sebelumnya selalu menetapkan CONFIG_STATE ke STALE dalam preferensi aplikasi bersama. Hal ini menunjukkan bahwa template Remote Config yang sudah tersimpan di aplikasi kini sudah usang karena telah dibuat template baru yang diupdate, yang publikasinya memicu fungsi tersebut. Update pengendali notifikasi Anda untuk menguji kondisi ini:

Swift

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

Mengambil update Remote Config saat aplikasi dimulai

Swift

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

Terakhir, tambahkan logika ke aplikasi Anda untuk memaksa pengambilan Remote Config dari jaringan (dengan mengabaikan penyimpanan lokal) karena CONFIG_STATE berstatus STALE. Jika aplikasi Anda terlalu sering mengambil dari jaringan, aplikasi tersebut dapat di-throttle oleh Firebase. Lihat Throttling.