欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用,并在之后根据需要轻松地扩大应用规模。立即报名

เผยแพร่การอัปเดตการกำหนดค่าระยะไกลแบบเรียลไทม์

การใช้ฟังก์ชันพื้นหลังการกำหนดค่าระยะไกลที่เรียกใช้โดย Cloud Functions for Firebase พร้อมกับ FCM คุณสามารถเผยแพร่การอัปเดตการกำหนดค่าระยะไกลได้แบบเรียลไทม์ ในสถานการณ์นี้ คุณจะสร้างฟังก์ชันที่ทริกเกอร์เมื่อคุณเผยแพร่หรือย้อนกลับเทมเพลตการกำหนดค่าระยะไกลจากแดชบอร์ดหรือ API การอัปเดตเทมเพลตจะทริกเกอร์ฟังก์ชันเพื่อส่งข้อความ FCM เพื่อให้ลูกค้าทราบว่าการกำหนดค่าที่มีอยู่นั้นเก่าแล้ว และการดึงข้อมูลครั้งต่อไปควรมาจากเซิร์ฟเวอร์:

ไดอะแกรมแสดงการอัปเดตการกำหนดค่าระยะไกลที่เรียกใช้การแจ้งเตือน FCM ผ่าน Cloud Functions

ส่วนที่เหลือของเอกสารนี้จะแนะนำคุณตลอดขั้นตอนเหล่านี้เพื่อเผยแพร่การอัปเดตการกำหนดค่าระยะไกลแบบเรียลไทม์

สมัครใช้งานอินสแตนซ์แอปไคลเอ็นต์ในหัวข้อ FCM

สำหรับการกำหนดเป้าหมายข้อความ FCM ไปยังอินสแตนซ์แอปไคลเอ็นต์กลุ่มใหญ่ เช่น ฐานผู้ใช้ทั้งหมด การส่งข้อความตามหัวข้อเป็นกลไกที่มีประสิทธิภาพมากที่สุด แต่ละอินสแตนซ์ของแอปที่ควรได้รับการอัพเดต Remote Config แบบเรียลไทม์ต้องสมัครรับข้อมูลจากชื่อหัวข้อ เช่น 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")
        }
    }
}
    

วัตถุประสงค์-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");
}
    

สร้างฟังก์ชันเพื่อส่ง 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 แล้วส่งข้อมูลนั้นเป็นเพย์โหลดข้อมูลของข้อความ FCM ไปยังไคลเอ็นต์ทั้งหมดที่สมัครรับหัวข้อ PUSH_RC

ตั้งค่าสถานะ Remote Config บนไคลเอนต์

เพย์โหลดข้อมูลที่แสดงในขั้นตอนก่อนหน้าจะตั้งค่า CONFIG_STATE เป็น STALE ในการตั้งค่าที่ใช้ร่วมกันของแอปเสมอ ซึ่งบ่งชี้ว่าเทมเพลต Remote Config ที่จัดเก็บไว้ในแอปนั้นไม่อัปเดตแล้วเนื่องจากมีการสร้างเทมเพลตที่อัปเดตใหม่ซึ่งมีการเผยแพร่เรียกใช้ฟังก์ชัน อัปเดตตัวจัดการการแจ้งเตือนของคุณเพื่อทดสอบเงื่อนไขนี้:

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

วัตถุประสงค์-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();
    }
}
    

เรียกการอัปเดตการกำหนดค่าระยะไกลเมื่อเริ่มต้นแอป

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

วัตถุประสงค์-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"));
                }
            });
}
    

สุดท้าย เพิ่มตรรกะให้กับแอปของคุณเพื่อบังคับให้ดึงการกำหนดค่าระยะไกลจากเครือข่าย (ละเว้นที่เก็บข้อมูลในเครื่อง) เพราะ CONFIG_STATE คือ STALE หากแอปดึงข้อมูลจากเครือข่ายบ่อยเกินไป Firebase อาจถูกควบคุมปริมาณ ดู การ ควบคุมปริมาณ