ย้ายแอป Parse iOS ของคุณไปยัง Firebase

หากคุณเป็นผู้ใช้ Parse ที่กำลังมองหาโซลูชัน Backend as a Service ทางเลือก Firebase อาจเป็นตัวเลือกที่เหมาะสมที่สุดสำหรับแอป iOS ของคุณ

คู่มือนี้จะอธิบายวิธีผสานรวมบริการเฉพาะเข้ากับแอปของคุณ สำหรับคำแนะนำการตั้งค่า Firebase ขั้นพื้นฐาน โปรดดูคู่มือ การตั้งค่า iOS+

Google Analytics

Google Analytics เป็นโซลูชันการวัดแอปฟรีที่ให้ข้อมูลเชิงลึกเกี่ยวกับการใช้งานแอปและการมีส่วนร่วมของผู้ใช้ Analytics ผสานรวมฟีเจอร์ต่างๆ ของ Firebase และมอบการรายงานแบบไม่จำกัดสำหรับเหตุการณ์ที่แตกต่างกันสูงสุด 500 เหตุการณ์ ซึ่งคุณสามารถกำหนดได้โดยใช้ Firebase SDK

ดู เอกสาร Google Analytics เพื่อเรียนรู้เพิ่มเติม

กลยุทธ์การย้ายถิ่นที่แนะนำ

การใช้ผู้ให้บริการวิเคราะห์หลายรายเป็นสถานการณ์ทั่วไปที่สามารถนำไปใช้กับ Google Analytics ได้อย่างง่ายดาย เพียงเพิ่มลงในแอปของคุณเพื่อรับประโยชน์จากเหตุการณ์และพร็อพเพอร์ตี้ผู้ใช้ที่ Analytics รวบรวมโดยอัตโนมัติ เช่น การเปิดครั้งแรก การอัปเดตแอป รุ่นอุปกรณ์ อายุ

สำหรับเหตุการณ์ที่กำหนดเองและคุณสมบัติผู้ใช้ คุณสามารถใช้กลยุทธ์การเขียนซ้ำได้โดยใช้ทั้ง Parse Analytics และ Google Analytics เพื่อบันทึกเหตุการณ์และคุณสมบัติ ซึ่งช่วยให้คุณค่อยๆ เปิดตัวโซลูชันใหม่ได้

การเปรียบเทียบรหัส

แยกวิเคราะห์

// Start collecting data
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];

NSDictionary *dimensions = @{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
};
// Send the dimensions to Parse along with the 'search' event
[PFAnalytics trackEvent:@"search" dimensions:dimensions];

Google Analytics

// Obtain the AppMeasurement instance and start collecting data
[FIRApp configure];

// Send the event with your params
[FIRAnalytics logEventWithName:@"search" parameters:@{
  // Define ranges to bucket data points into meaningful segments
  @"priceRange": @"1000-1500",
  // Did the user filter the query?
  @"source": @"craigslist",
  // Do searches happen more often on weekdays or weekends?
  @"dayType": @"weekday"
}];

ฐานข้อมูลเรียลไทม์ Firebase

ฐานข้อมูลเรียลไทม์ Firebase เป็นฐานข้อมูล NoSQL ที่โฮสต์บนคลาวด์ ข้อมูลจะถูกจัดเก็บเป็น JSON และซิงโครไนซ์แบบเรียลไทม์กับไคลเอนต์ที่เชื่อมต่อทุกตัว

ดู เอกสารฐานข้อมูล Firebase Realtime เพื่อเรียนรู้เพิ่มเติม

ความแตกต่างกับข้อมูลแยกวิเคราะห์

วัตถุ

ใน Parse คุณจัดเก็บ PFObject หรือคลาสย่อยของ PFObject ที่มีคู่คีย์-ค่าของข้อมูลที่เข้ากันได้กับ JSON ข้อมูลไม่มีสคีมา ซึ่งหมายความว่าคุณไม่จำเป็นต้องระบุคีย์ที่มีอยู่ใน PFObject แต่ละรายการ

ข้อมูลฐานข้อมูล Firebase Realtime ทั้งหมดถูกจัดเก็บเป็นออบเจ็กต์ JSON และไม่มีอะไรเทียบเท่ากับ PFObject คุณเพียงแค่เขียนลงในค่าแผนผัง JSON ของประเภทที่สอดคล้องกับประเภท JSON ที่มีอยู่

ต่อไปนี้คือตัวอย่างวิธีที่คุณอาจบันทึกคะแนนสูงสุดสำหรับเกมได้

แยกวิเคราะห์
PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"];
gameScore[@"score"] = @1337;
gameScore[@"playerName"] = @"Sean Plott";
gameScore[@"cheatMode"] = @NO;
[gameScore saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succeeded) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
ฐานไฟ
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
NSString *key = [[ref child:@"scores"] childByAutoId].key;
NSDictionary *score = @{@"score": @1337,
                        @"playerName": @"Sean Plott",
                        @"cheatMode": @NO};
[key setValue:score withCompletionBlock:^(NSError *error,  FIRDatabaseReference *ref) {
  if (error) {
    // The object has been saved.
  } else {
    // There was a problem, check error.description
  }
}];
สำหรับรายละเอียดเพิ่มเติม โปรดดูคู่มือ การอ่านและเขียนข้อมูลบนแพลตฟอร์ม Apple

ความสัมพันธ์ระหว่างข้อมูล

PFObject สามารถมีความสัมพันธ์กับ PFObject อื่นได้ : วัตถุใด ๆ สามารถใช้วัตถุอื่นเป็นค่าได้

ใน Firebase Realtime Database ความสัมพันธ์จะแสดงได้ดีกว่าโดยใช้โครงสร้างข้อมูลแบบเรียบที่แยกข้อมูลออกเป็นพาธแยกกัน เพื่อให้สามารถดาวน์โหลดได้อย่างมีประสิทธิภาพในการเรียกแยกกัน

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

แยกวิเคราะห์
// Create the author
PFObject *myAuthor = [PFObject objectWithClassName:@"Author"];
myAuthor[@"name"] = @"Grace Hopper";
myAuthor[@"birthDate"] = @"December 9, 1906";
myAuthor[@"nickname"] = @"Amazing Grace";

// Create the post
PFObject *myPost = [PFObject objectWithClassName:@"Post"];
myPost[@"title"] = @"Announcing COBOL, a New Programming Language";

// Add a relation between the Post and the Author
myPost[@"parent"] = myAuthor;

// This will save both myAuthor and myPost
[myPost saveInBackground];
ฐานไฟ
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// Create the author
NSString *myAuthorKey = @"ghopper";
NSDictionary *author = @{@"name": @"Grace Hopper",
                         @"birthDate": @"December 9, 1906",
                         @"nickname": @"Amazing Grace"};
// Save the author
[[ref child:myAuthorKey] setValue:author]

// Create and save the post
NSString *key = [[ref child:@"posts"] childByAutoId].key;
NSDictionary *post = @{@"author": myAuthorKey,
                       @"title": @"Announcing COBOL, a New Programming Language"};
[key setValue:post]

ผลลัพธ์ที่ได้คือโครงร่างข้อมูลต่อไปนี้

{
  // Info about the authors
  "authors": {
    "ghopper": {
      "name": "Grace Hopper",
      "date_of_birth": "December 9, 1906",
      "nickname": "Amazing Grace"
    },
    ...
  },
  // Info about the posts: the "author" fields contains the key for the author
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "ghopper",
      "title": "Announcing COBOL, a New Programming Language"
    }
    ...
  }
}
สำหรับรายละเอียดเพิ่มเติม โปรดดูคู่มือ โครงสร้างฐานข้อมูลของคุณ

การอ่านข้อมูล

ใน Parse คุณอ่านข้อมูลโดยใช้ ID ของวัตถุ Parse เฉพาะหรือดำเนินการค้นหาโดยใช้ PFQuery

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

ต่อไปนี้คือตัวอย่างวิธีที่คุณสามารถดึงคะแนนสำหรับผู้เล่นคนใดคนหนึ่ง โดยยึดตามตัวอย่างที่นำเสนอในส่วน "ออบเจ็กต์"

แยกวิเคราะห์
PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query whereKey:@"playerName" equalTo:@"Dan Stemkoski"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
  if (!error) {
    for (PFObject *score in objects) {
      NSString *gameScore = score[@"score"];
      NSLog(@"Retrieved: %@", gameScore);
    }
  } else {
    // Log details of the failure
    NSLog(@"Error: %@ %@", error, [error userInfo]);
  }
}];
ฐานไฟ
// Create a reference to the database
FIRDatabaseReference *ref = [[FIRDatabase database] reference];

// This type of listener is not one time, and you need to cancel it to stop
// receiving updates.
[[[[ref child:@"scores"] queryOrderedByChild:@"playerName"] queryEqualToValue:@"Dan Stemkoski"]
    observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
  // This will fire for each matching child node.
  NSDictionary *score = snapshot.value;
  NSString gameScore = score[@"score"];
  NSLog(@"Retrieved: %@", gameScore);
}];
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับประเภท Listener เหตุการณ์ที่มีอยู่ และวิธีการสั่งซื้อและกรองข้อมูล โปรดดูคู่มือ การอ่านและเขียนข้อมูลบนแพลตฟอร์ม Apple

กลยุทธ์การย้ายถิ่นที่แนะนำ

คิดใหม่ข้อมูลของคุณ

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

  • วิธีที่วัตถุแยกวิเคราะห์ของคุณควรแมปกับข้อมูล Firebase
  • หากคุณมีความสัมพันธ์ระหว่างพ่อแม่และลูก วิธีแบ่งข้อมูลของคุณตามเส้นทางต่างๆ เพื่อให้สามารถดาวน์โหลดได้อย่างมีประสิทธิภาพในการเรียกแยกกัน

ย้ายข้อมูลของคุณ

หลังจากที่คุณตัดสินใจได้ว่าจะจัดโครงสร้างข้อมูลใน Firebase อย่างไร คุณจะต้องวางแผนวิธีจัดการกับช่วงเวลาที่แอปของคุณจะต้องเขียนลงฐานข้อมูลทั้งสอง ทางเลือกของคุณคือ:

ซิงค์พื้นหลัง

ในสถานการณ์นี้ คุณมีแอปสองเวอร์ชัน: เวอร์ชันเก่าที่ใช้ Parse และเวอร์ชันใหม่ที่ใช้ Firebase การซิงค์ระหว่างฐานข้อมูลทั้งสองได้รับการจัดการโดย Parse Cloud Code (Parse to Firebase) โดยโค้ดของคุณรับฟังการเปลี่ยนแปลงบน Firebase และซิงค์การเปลี่ยนแปลงเหล่านั้นกับ Parse ก่อนที่คุณจะเริ่มใช้เวอร์ชันใหม่ได้ คุณต้อง:

  • แปลงข้อมูลแยกวิเคราะห์ที่มีอยู่ของคุณให้เป็นโครงสร้าง Firebase ใหม่ และเขียนลงในฐานข้อมูลเรียลไทม์ของ Firebase
  • เขียนฟังก์ชัน Parse Cloud Code ที่ใช้ Firebase REST API เพื่อเขียนไปยังการเปลี่ยนแปลงฐานข้อมูล Firebase Realtime ที่ทำใน Parse Data โดยไคลเอนต์เก่า
  • เขียนและปรับใช้โค้ดที่รับฟังการเปลี่ยนแปลงบน Firebase และซิงค์กับฐานข้อมูล Parse

สถานการณ์นี้ช่วยให้มั่นใจได้ถึงการแยกโค้ดเก่าและใหม่อย่างชัดเจน และทำให้ไคลเอ็นต์เรียบง่าย ความท้าทายของสถานการณ์นี้คือการจัดการชุดข้อมูลขนาดใหญ่ในการส่งออกครั้งแรก และการทำให้แน่ใจว่าการซิงค์แบบสองทิศทางจะไม่สร้างการเรียกซ้ำแบบไม่มีที่สิ้นสุด

เขียนสองครั้ง

ในสถานการณ์นี้ คุณจะเขียนแอปเวอร์ชันใหม่ที่ใช้ทั้ง Firebase และ Parse โดยใช้ Parse Cloud Code เพื่อซิงค์การเปลี่ยนแปลงที่ทำโดยไคลเอนต์เก่าจาก Parse Data ไปยัง Firebase Realtime Database เมื่อมีคนย้ายจากแอปเวอร์ชัน Parse-only มากพอแล้ว คุณสามารถลบโค้ด Parse ออกจากเวอร์ชันการเขียนซ้ำได้

สถานการณ์นี้ไม่จำเป็นต้องมีโค้ดฝั่งเซิร์ฟเวอร์ ข้อเสียคือข้อมูลที่ไม่มีการเข้าถึงจะไม่ถูกย้าย และขนาดแอปของคุณจะเพิ่มขึ้นตามการใช้งาน SDK ทั้งสอง

การรับรองความถูกต้องของ Firebase

การตรวจสอบสิทธิ์ Firebase สามารถตรวจสอบสิทธิ์ผู้ใช้โดยใช้รหัสผ่านและผู้ให้บริการข้อมูลประจำตัวส่วนกลางยอดนิยม เช่น Google, Facebook และ Twitter นอกจากนี้ยังมีไลบรารี UI เพื่อช่วยคุณประหยัดการลงทุนที่สำคัญที่จำเป็นในการนำไปใช้และรักษาประสบการณ์การตรวจสอบสิทธิ์อย่างเต็มรูปแบบสำหรับแอปของคุณในทุกแพลตฟอร์ม

ดู เอกสารการรับรองความถูกต้องของ Firebase เพื่อเรียนรู้เพิ่มเติม

ความแตกต่างกับ Parse Auth

Parse มีคลาสผู้ใช้เฉพาะที่เรียกว่า PFUser ซึ่งจะจัดการฟังก์ชันที่จำเป็นสำหรับการจัดการบัญชีผู้ใช้โดยอัตโนมัติ PFUser เป็นคลาสย่อยของ PFObject ซึ่งหมายความว่าข้อมูลผู้ใช้มีอยู่ใน Parse Data และสามารถขยายด้วยฟิลด์เพิ่มเติมได้เช่นเดียวกับ PFObject อื่นๆ

FIRUser มีชุดคุณสมบัติพื้นฐานคงที่ ได้แก่ ID เฉพาะ ที่อยู่อีเมลหลัก ชื่อ และ URL รูปภาพ ซึ่งจัดเก็บไว้ในฐานข้อมูลผู้ใช้ของโปรเจ็กต์ที่แยกต่างหาก ผู้ใช้สามารถอัพเดตคุณสมบัติเหล่านั้นได้ คุณไม่สามารถเพิ่มคุณสมบัติอื่นให้กับวัตถุ FIRUser ได้โดยตรง คุณสามารถจัดเก็บคุณสมบัติเพิ่มเติมไว้ในฐานข้อมูลเรียลไทม์ Firebase ของคุณได้แทน

ต่อไปนี้เป็นตัวอย่างของวิธีที่คุณอาจลงทะเบียนผู้ใช้และเพิ่มฟิลด์หมายเลขโทรศัพท์เพิ่มเติม

แยกวิเคราะห์
PFUser *user = [PFUser user];
user.username = @"my name";
user.password = @"my pass";
user.email = @"email@example.com";

// other fields can be set just like with PFObject
user[@"phone"] = @"415-392-0202";

[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (!error) {
    // Hooray! Let them use the app now.
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];
ฐานไฟ
[[FIRAuth auth] createUserWithEmail:@"email@example.com"
                           password:@"my pass"
                         completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
  if (!error) {
    FIRDatabaseReference *ref = [[FIRDatabase database] reference];
    [[[[ref child:@"users"] child:user.uid] child:@"phone"] setValue:@"415-392-0202"
  } else {
    // Something went wrong
    NSString *errorString = [error userInfo][@"error"];
  }
}];

กลยุทธ์การย้ายถิ่นที่แนะนำ

ย้ายบัญชี

หากต้องการย้ายบัญชีผู้ใช้จาก Parse ไปยัง Firebase ให้ส่งออกฐานข้อมูลผู้ใช้ของคุณไปยังไฟล์ JSON หรือ CSV จากนั้นนำเข้าไฟล์ไปยังโปรเจ็กต์ Firebase ของคุณโดยใช้คำสั่ง auth:import ของ Firebase CLI

ขั้นแรก ส่งออกฐานข้อมูลผู้ใช้ของคุณจากคอนโซล Parse หรือฐานข้อมูลที่คุณโฮสต์เอง ตัวอย่างเช่น ไฟล์ JSON ที่ส่งออกจากคอนโซล Parse อาจมีลักษณะดังนี้:

{ // Username/password user
  "bcryptPassword": "$2a$10$OBp2hxB7TaYZgKyTiY48luawlTuYAU6BqzxJfpHoJMdZmjaF4HFh6",
  "email": "user@example.com",
  "username": "testuser",
  "objectId": "abcde1234",
  ...
},
{ // Facebook user
  "authData": {
    "facebook": {
      "access_token": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "expiration_date": "2017-01-02T03:04:05.006Z",
      "id": "1000000000"
    }
  },
  "username": "wXyZ987654321StUv",
  "objectId": "fghij5678",
  ...
}

จากนั้นแปลงไฟล์ที่ส่งออกเป็นรูปแบบที่ Firebase CLI ต้องการ ใช้ objectId ของผู้ใช้ Parse ของคุณเป็น localId ของผู้ใช้ Firebase ของคุณ นอกจากนี้ base64 เข้ารหัสค่า bcryptPassword จาก Parse และใช้ในฟิลด์ passwordHash ตัวอย่างเช่น:

{
  "users": [
    {
      "localId": "abcde1234",  // Parse objectId
      "email": "user@example.com",
      "displayName": "testuser",
      "passwordHash": "JDJhJDEwJE9CcDJoeEI3VGFZWmdLeVRpWTQ4bHVhd2xUdVlBVTZCcXp4SmZwSG9KTWRabWphRjRIRmg2",
    },
    {
      "localId": "fghij5678",  // Parse objectId
      "displayName": "wXyZ987654321StUv",
      "providerUserInfo": [
        {
          "providerId": "facebook.com",
          "rawId": "1000000000",  // Facebook ID
        }
      ]
    }
  ]
}

สุดท้าย นำเข้าไฟล์ที่แปลงแล้วด้วย Firebase CLI โดยระบุ bcrypt เป็นอัลกอริธึมแฮช:

firebase auth:import account_file.json --hash-algo=BCRYPT

ย้ายข้อมูลผู้ใช้

หากคุณกำลังจัดเก็บข้อมูลเพิ่มเติมสำหรับผู้ใช้ของคุณ คุณสามารถย้ายข้อมูลดังกล่าวไปยังฐานข้อมูลเรียลไทม์ Firebase ได้โดยใช้กลยุทธ์ที่อธิบายไว้ในส่วน การย้ายข้อมูล หากคุณย้ายบัญชีโดยใช้ขั้นตอนที่อธิบายไว้ในส่วน การย้ายบัญชี บัญชี Firebase ของคุณจะมี ID เดียวกันกับบัญชี Parse ของคุณ ช่วยให้คุณสามารถย้ายและสร้างความสัมพันธ์ใดๆ ที่คีย์โดย ID ผู้ใช้ได้อย่างง่ายดาย

การส่งข้อความบนคลาวด์ของ Firebase

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

ดู เอกสาร Firebase Cloud Messaging เพื่อเรียนรู้เพิ่มเติม

ความแตกต่างกับการแจ้งเตือนแบบแยกวิเคราะห์

แอปพลิเคชัน Parse ทุกตัวที่ติดตั้งบนอุปกรณ์ที่ลงทะเบียนสำหรับการแจ้งเตือนมีออบเจ็กต์ Installation ที่เกี่ยวข้อง ซึ่งคุณเก็บข้อมูลทั้งหมดที่จำเป็นในการกำหนดเป้าหมายการแจ้งเตือน Installation เป็นคลาสย่อยของ PFUser ซึ่งหมายความว่าคุณสามารถเพิ่มข้อมูลเพิ่มเติมใดๆ ที่คุณต้องการให้กับอินสแตนซ์ Installation ของคุณได้

ตัวเขียนการแจ้งเตือนจะแสดงกลุ่มผู้ใช้ที่กำหนดไว้ล่วงหน้าโดยอิงตามข้อมูล เช่น แอพ เวอร์ชันแอพ และภาษาของอุปกรณ์ คุณสามารถสร้างกลุ่มผู้ใช้ที่ซับซ้อนมากขึ้นได้โดยใช้เหตุการณ์และพร็อพเพอร์ตี้ของ Google Analytics เพื่อสร้างกลุ่มเป้าหมาย ดูคู่มือช่วยเหลือ ผู้ชม เพื่อเรียนรู้เพิ่มเติม ข้อมูลการกำหนดเป้าหมายเหล่านี้จะไม่ปรากฏในฐานข้อมูล Firebase Realtime

กลยุทธ์การย้ายถิ่นที่แนะนำ

การย้ายโทเค็นอุปกรณ์

ในขณะที่ Parse ใช้โทเค็นอุปกรณ์ APN เพื่อกำหนดเป้าหมายการติดตั้งสำหรับการแจ้งเตือน FCM จะใช้โทเค็นการลงทะเบียน FCM ที่แมปกับโทเค็นอุปกรณ์ APN เพียงเพิ่ม FCM SDK ลงในแอป Apple ของคุณ จากนั้นแอปจะ ดึงโทเค็น FCM โดยอัตโนมัติ

การย้ายช่องไปยังหัวข้อ FCM

หากคุณใช้ช่องแยกวิเคราะห์เพื่อส่งการแจ้งเตือน คุณสามารถย้ายไปยังหัวข้อ FCM ซึ่งมีรูปแบบผู้เผยแพร่และสมาชิกเดียวกัน ในการจัดการการเปลี่ยนจาก Parse เป็น FCM คุณสามารถเขียนแอปเวอร์ชันใหม่ที่ใช้ Parse SDK เพื่อยกเลิกการสมัครจากช่อง Parse และ FCM SDK เพื่อสมัครรับหัวข้อ FCM ที่เกี่ยวข้อง

ตัวอย่างเช่น หากผู้ใช้ของคุณสมัครรับหัวข้อ "Giants" คุณจะดำเนินการดังนี้:

PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation removeObject:@"Giants" forKey:@"channels"];
[currentInstallation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
  if (succeeded) {
    [[FIRMessaging messaging] subscribeToTopic:@"/topics/Giants"];
  } else {
    // Something went wrong unsubscribing
  }
}];

เมื่อใช้กลยุทธ์นี้ คุณสามารถส่งข้อความไปยังทั้งช่อง Parse และหัวข้อ FCM ที่เกี่ยวข้อง ซึ่งรองรับผู้ใช้ทั้งเวอร์ชันเก่าและเวอร์ชันใหม่ เมื่อมีผู้ใช้ย้ายจากแอปเวอร์ชัน Parse-only มากพอแล้ว คุณสามารถหยุดเวอร์ชันนั้นและเริ่มส่งโดยใช้ FCM เท่านั้น

ดู เอกสารหัวข้อ FCM เพื่อเรียนรู้เพิ่มเติม

การกำหนดค่าระยะไกลของ Firebase

Firebase Remote Config เป็นบริการระบบคลาวด์ที่ช่วยให้คุณเปลี่ยนลักษณะการทำงานและรูปลักษณ์ของแอปได้โดยไม่ต้องให้ผู้ใช้ดาวน์โหลดการอัปเดตแอป เมื่อใช้การกำหนดค่าระยะไกล คุณจะสร้างค่าเริ่มต้นในแอปที่ควบคุมลักษณะการทำงานและรูปลักษณ์ของแอปของคุณ จากนั้น คุณจะใช้คอนโซล Firebase เพื่อลบล้างค่าเริ่มต้นในแอปสำหรับผู้ใช้แอปทั้งหมดหรือกลุ่มฐานผู้ใช้ของคุณได้ในภายหลัง

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

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการกำหนดค่าระยะไกลของ Firebase โปรดดู บทแนะนำการกำหนดค่าระยะไกล

ความแตกต่างกับการกำหนดค่าแยกวิเคราะห์

ด้วย Parse config คุณสามารถเพิ่มคู่คีย์/ค่าให้กับแอปของคุณบน Parse Config Dashboard จากนั้นดึง PFConfig บนไคลเอนต์ ทุกอินสแตนซ์ PFConfig ที่คุณได้รับจะไม่เปลี่ยนรูปแบบเสมอ เมื่อคุณเรียก PFConfig ใหม่จากเครือข่ายในอนาคต อินสแตนซ์นั้นจะไม่แก้ไขอินสแตนซ์ PFConfig ใดๆ ที่มีอยู่ แต่จะสร้างอินสแตนซ์ใหม่แทนและทำให้พร้อมใช้งานผ่าน currentConfig

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

กลยุทธ์การย้ายถิ่นที่แนะนำ

คุณสามารถย้ายไปยัง Firebase Remote Config ได้โดยการคัดลอกคู่คีย์/ค่าของการกำหนดค่า Parse ของคุณไปยังคอนโซล Firebase จากนั้นปรับใช้แอปเวอร์ชันใหม่ที่ใช้ Firebase Remote Config

หากคุณต้องการทดลองใช้ทั้ง Parse Config และ Firebase Remote Config คุณสามารถปรับใช้แอปเวอร์ชันใหม่ที่ใช้ SDK ทั้งสองได้จนกว่าผู้ใช้จะย้ายจากเวอร์ชัน Parse เท่านั้นมากพอ

การเปรียบเทียบรหัส

แยกวิเคราะห์

[PFConfig getConfigInBackgroundWithBlock:^(PFConfig *config, NSError *error) {
  if (!error) {
    NSLog(@"Yay! Config was fetched from the server.");
  } else {
    NSLog(@"Failed to fetch. Using Cached Config.");
    config = [PFConfig currentConfig];
  }

  NSString *welcomeMessage = config[@"welcomeMessage"];
  if (!welcomeMessage) {
    NSLog(@"Falling back to default message.");
    welcomeMessage = @"Welcome!";
  }
}];

ฐานไฟ

FIRRemoteConfig remoteConfig = [FIRRemoteConfig remoteConfig];
// Set defaults from a plist file
[remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"];

[remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
  if (status == FIRRemoteConfigFetchStatusSuccess) {
    NSLog(@"Yay! Config was fetched from the server.");
    // Once the config is successfully fetched it must be activated before newly fetched
    // values are returned.
    [self.remoteConfig activateFetched];
  } else {
    NSLog(@"Failed to fetch. Using last fetched or default.");
  }
}];

// ...

// When this is called, the value of the latest fetched and activated config is returned;
// if there's none, the default value is returned.
NSString welcomeMessage = remoteConfig[@"welcomeMessage"].stringValue;