การเรียกข้อมูลด้วยฐานข้อมูลเรียลไทม์ของ Firebase สำหรับ C++

เอกสารนี้ครอบคลุมพื้นฐานของการดึงข้อมูล รวมถึงวิธีจัดเรียงและกรองข้อมูล Firebase

ก่อนเริ่มต้น

ตรวจสอบว่าคุณได้ตั้งค่าแอปและเข้าถึงฐานข้อมูลตามที่ระบุไว้ใน คู่มือ Get Started

กำลังดึงข้อมูล

ระบบจะเรียกข้อมูล Firebase โดยการเรียกใช้ GetValue() เพียงครั้งเดียวหรือ แนบกับ ValueListener ในการอ้างอิง FirebaseDatabase ระบบจะเรียกใช้ listener ของค่า 1 ครั้งสำหรับสถานะเริ่มต้นของข้อมูล และอีกครั้งเมื่อใดก็ตามที่ข้อมูลมีการเปลี่ยนแปลง

รับ DatabaseReference

หากต้องการเขียนข้อมูลลงในฐานข้อมูล คุณต้องมีอินสแตนซ์ของ DatabaseReference

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

อ่านข้อมูลครั้งเดียว

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

  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").GetValue();

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

  // In the game loop that polls for the result...

  if (result.status() != firebase::kFutureStatusPending) {
    if (result.status() != firebase::kFutureStatusComplete) {
      LogMessage("ERROR: GetValue() returned an invalid result.");
      // Handle the error...
    } else if (result.error() != firebase::database::kErrorNone) {
      LogMessage("ERROR: GetValue() returned error %d: %s", result.error(),
                 result.error_message());
      // Handle the error...
    } else {
      firebase::database::DataSnapshot snapshot = result.result();
      // Do something with the snapshot...
    }
  }

ซึ่งแสดงการตรวจสอบข้อผิดพลาดขั้นพื้นฐานบางอย่าง โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบข้อผิดพลาดและวิธีพิจารณาว่าผลลัพธ์พร้อมเมื่อใดในข้อมูลอ้างอิง firebase::Future

ฟังเหตุการณ์

คุณเพิ่ม Listener เพื่อติดตามการเปลี่ยนแปลงข้อมูลได้โดยทำดังนี้

ValueListener คลาสพื้นฐาน

ติดต่อกลับ การใช้งานทั่วไป
OnValueChanged อ่านและฟังการเปลี่ยนแปลงเนื้อหาทั้งหมดของเส้นทาง

OnChildListener คลาสพื้นฐาน

OnChildAdded ดึงข้อมูลรายการหรือฟังการเพิ่มรายการลงในลิสต์ การใช้งานที่แนะนำกับ OnChildChanged และ OnChildRemoved เพื่อตรวจสอบการเปลี่ยนแปลงในรายการ
OnChildChanged ฟังการเปลี่ยนแปลงของรายการในลิสต์ ใช้กับ OnChildAdded และ OnChildRemoved เพื่อตรวจสอบ การเปลี่ยนแปลงในรายการ
OnChildRemoved ฟังรายการที่ถูกนำออกจากลิสต์ ใช้กับ OnChildAdded และ OnChildChanged เพื่อตรวจสอบ การเปลี่ยนแปลงในรายการ
OnChildMoved ฟังการเปลี่ยนแปลงลำดับของรายการในรายการที่เรียงลำดับ OnChildMoved การเรียกกลับจะเป็นไปตาม OnChildChanged การเรียกกลับเนื่องจากการเปลี่ยนแปลงลำดับของสินค้า (ขึ้นอยู่กับวิธีการจัดเรียงปัจจุบัน) เสมอ

คลาส ValueListener

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

ตัวอย่างต่อไปนี้แสดงเกมที่ดึงคะแนนของลีดเดอร์บอร์ด จากฐานข้อมูล

  class LeadersValueListener : public firebase::database::ValueListener {
   public:
    void OnValueChanged(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code,
                 error_message);
    }
  };

  // Elsewhere in the code...

  LeadersValueListener* listener = new LeadersValueListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

Future&ltDataSnapshot&gt ผลลัพธ์มีข้อมูลในตำแหน่งที่ระบุ ในฐานข้อมูล ณ เวลาที่เกิดเหตุการณ์ การเรียกใช้ value() ในสแนปชอต จะแสดงผล Variant ที่แสดงข้อมูล

ในตัวอย่างนี้ ระบบจะลบล้างเมธอด OnCancelled ด้วยเพื่อดูว่ามีการยกเลิกการอ่านหรือไม่ เช่น การอ่านอาจถูกยกเลิกหากไคลเอ็นต์ไม่มีสิทธิ์อ่านจากตำแหน่งฐานข้อมูล Firebase database::Error จะ ระบุสาเหตุที่ทำให้เกิดข้อผิดพลาด

คลาส ChildListener

เหตุการณ์ของโหนดลูกจะทริกเกอร์เพื่อตอบสนองต่อการดำเนินการที่เฉพาะเจาะจงซึ่งเกิดขึ้นกับ โหนดลูกจากการดำเนินการ เช่น การเพิ่มโหนดลูกใหม่ผ่านเมธอด PushChild() หรือการอัปเดตโหนดลูกผ่านเมธอด UpdateChildren() การใช้ฟีเจอร์เหล่านี้ร่วมกันจะมีประโยชน์ในการฟังการเปลี่ยนแปลงของโหนดที่เฉพาะเจาะจงในฐานข้อมูล ตัวอย่างเช่น เกมอาจใช้วิธีการเหล่านี้ร่วมกันเพื่อตรวจสอบกิจกรรมในความคิดเห็นของเซสชันเกม ดังที่แสดงด้านล่าง

  class SessionCommentsChildListener : public firebase::database::ChildListener {
   public:
    void OnChildAdded(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildChanged(const firebase::database::DataSnapshot& snapshot,
                        const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnChildRemoved(
        const firebase::database::DataSnapshot& snapshot) override {
      // Do something with the data in snapshot ...
    }
    void OnChildMoved(const firebase::database::DataSnapshot& snapshot,
                      const char* previous_sibling) override {
      // Do something with the data in snapshot ...
    }
    void OnCancelled(const firebase::database::Error& error_code,
                     const char* error_message) override {
      LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s",
                 error_code, error_message);
    }
  };

  // elsewhere ....

  SessionCommentsChildListener* listener = new SessionCommentsChildListener();
  firebase::Future&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

โดยปกติจะใช้การเรียกกลับ OnChildAdded เพื่อเรียกรายการ ในฐานข้อมูล Firebase ระบบจะเรียกใช้OnChildAddedการเรียกกลับ 1 ครั้ง สำหรับเด็กที่มีอยู่แต่ละคน แล้วเรียกใช้อีกครั้งทุกครั้งที่มีการเพิ่มเด็กใหม่ลงในเส้นทางที่ระบุ ระบบจะส่งสแนปชอตที่มีข้อมูลของบุตรหลานคนใหม่ให้ผู้ฟัง

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

ระบบจะทริกเกอร์OnChildRemovedการเรียกกลับเมื่อนำองค์ประกอบย่อยที่อยู่ติดกันออก โดยปกติจะใช้ร่วมกับแฮนเดิล OnChildAdded และ OnChildChanged สแนปชอตที่ส่งไปยังการเรียกกลับมี ข้อมูลสำหรับบุตรหลานที่ถูกนำออก

OnChildMovedการเรียกกลับจะทริกเกอร์เมื่อใดก็ตามที่OnChildChanged การเรียกเกิดขึ้นจากการอัปเดตที่ทำให้มีการจัดลำดับใหม่ขององค์ประกอบย่อย ใช้กับข้อมูลที่จัดเรียงด้วย OrderByChild หรือ OrderByValue

การจัดเรียงและการกรองข้อมูล

คุณใช้คลาส Realtime Database Query เพื่อดึงข้อมูลที่จัดเรียงตามคีย์ ตามค่า หรือตามค่าของรายการย่อยได้ นอกจากนี้ คุณยังกรอง ผลลัพธ์ที่จัดเรียงแล้วให้เหลือจำนวนผลลัพธ์ที่เฉพาะเจาะจงหรือช่วงของคีย์หรือ ค่าได้ด้วย

จัดเรียงข้อมูล

หากต้องการดึงข้อมูลที่จัดเรียงแล้ว ให้เริ่มโดยการระบุเมธอด order-by อย่างใดอย่างหนึ่งเพื่อ กำหนดวิธีจัดเรียงผลลัพธ์

วิธีการ การใช้งาน
OrderByChild() จัดเรียงผลลัพธ์ตามค่าของคีย์ย่อยที่ระบุ
OrderByKey() จัดเรียงผลลัพธ์ตามคีย์ย่อย
OrderByValue() จัดเรียงผลลัพธ์ตามค่าของรายการย่อย

คุณใช้วิธีการจัดเรียงได้วิธีเดียวในแต่ละครั้ง การเรียกใช้เมธอด Order-by หลายครั้งในคำค้นหาเดียวกันจะทำให้เกิดข้อผิดพลาด

ตัวอย่างต่อไปนี้แสดงวิธีที่คุณจะติดตามลีดเดอร์บอร์ดคะแนน ที่จัดเรียงตามคะแนนได้

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score");

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

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

การเรียกใช้เมธอด OrderByChild() จะระบุคีย์ย่อยเพื่อจัดเรียง ผลลัพธ์ ในกรณีนี้ ระบบจะจัดเรียงผลลัพธ์ตามค่าของ"score" ค่าในแต่ละรายการย่อย ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่วิธีจัดเรียงข้อมูลการค้นหา

การกรองข้อมูล

หากต้องการกรองข้อมูล คุณสามารถรวมวิธีการจำกัดหรือช่วงใดก็ได้กับวิธีการ จัดเรียงตามเมื่อสร้างคําค้นหา

วิธีการ การใช้งาน
LimitToFirst() กำหนดจำนวนสูงสุดของรายการที่จะแสดงจากจุดเริ่มต้นของ รายการผลการค้นหาที่เรียงลำดับ
LimitToLast() กำหนดจำนวนสูงสุดของรายการที่จะแสดงจากท้ายรายการผลลัพธ์ที่เรียงลำดับ
StartAt() แสดงรายการที่มากกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับวิธีการจัดเรียงที่เลือก
EndAt() แสดงรายการที่มีค่าน้อยกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับวิธีการจัดเรียงที่เลือก
EqualTo() แสดงรายการที่เท่ากับคีย์หรือค่าที่ระบุ โดยขึ้นอยู่กับวิธีการจัดเรียงที่เลือก

คุณรวมฟังก์ชัน limit หรือ range หลายรายการได้ ซึ่งต่างจากเมธอด order-by เช่น คุณสามารถรวมเมธอด StartAt() และ EndAt() เพื่อจำกัด ผลลัพธ์ให้อยู่ในช่วงค่าที่ระบุ

แม้ว่าจะมีผลการค้นหาที่ตรงกันเพียงรายการเดียว แต่สแนปชอตก็ยังคงเป็นลิสต์ เพียงแต่มีรายการเดียวเท่านั้น

จำกัดจำนวนผลลัพธ์

คุณสามารถใช้วิธี LimitToFirst() และ LimitToLast() เพื่อตั้งค่า จำนวนบุตรหลานสูงสุดที่จะซิงค์สำหรับการเรียกกลับที่ระบุ เช่น หากคุณใช้ LimitToFirst() เพื่อตั้งค่าขีดจำกัดเป็น 100 ในตอนแรกคุณจะได้รับการเรียกกลับ OnChildAdded สูงสุด 100 รายการเท่านั้น หากคุณมีรายการที่จัดเก็บไว้ในฐานข้อมูล Firebase น้อยกว่า 100 รายการ OnChildAddedการเรียกกลับจะทริกเกอร์สำหรับแต่ละรายการ

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

ตัวอย่างเช่น โค้ดด้านล่างจะแสดงคะแนนสูงสุดจากลีดเดอร์บอร์ด

  firebase::database::Query query =
    dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1);

  // To get the resulting DataSnapshot either use query.GetValue() and poll the
  // future, or use query.AddValueListener() and register to handle the
  // OnValueChanged callback.

กรองตามคีย์หรือค่า

คุณใช้ StartAt(), EndAt() และ EqualTo() เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดเทียบเท่าที่กำหนดเองสำหรับคำค้นหาได้ ซึ่งอาจมีประโยชน์ในการ แบ่งหน้าข้อมูลหรือค้นหารายการที่มีรายการย่อยซึ่งมีค่าที่เฉพาะเจาะจง

วิธีกำหนดลำดับข้อมูลการค้นหา

ส่วนนี้จะอธิบายวิธีจัดเรียงข้อมูลตามวิธีการจัดเรียงแต่ละวิธีในคลาส Query

OrderByChild

เมื่อใช้ OrderByChild() ข้อมูลที่มีคีย์ย่อยที่ระบุจะ จัดเรียงดังนี้

  1. เด็กที่มีค่า null สำหรับคีย์ของเด็กที่ระบุจะแสดงก่อน
  2. จากนั้นจะเป็นเด็กที่มีค่า false สำหรับคีย์ย่อยที่ระบุ หากมีบุตรหลายคนที่มีค่าเป็น false ระบบจะ จัดเรียงตามพจนานุกรมตามคีย์
  3. จากนั้นจะเป็นเด็กที่มีค่า true สำหรับคีย์ย่อยที่ระบุ หากมีบุตรหลายคนที่มีค่าเป็น true ระบบจะ จัดเรียงตามพจนานุกรมตามคีย์
  4. จากนั้นจะเป็นชื่อที่มีค่าตัวเลข โดยเรียงลำดับจากน้อยไปมาก หากโหนดย่อยหลายรายการมีค่าตัวเลขเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามคีย์
  5. สตริงจะอยู่หลังตัวเลขและจัดเรียงตามลำดับตัวอักษรจากน้อยไปมาก หากโหนดย่อยหลายรายการมีค่าเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามพจนานุกรมตามคีย์
  6. ออบเจ็กต์จะอยู่สุดท้ายและจัดเรียงตามพจนานุกรมตามคีย์จากน้อยไปมาก

OrderByKey

เมื่อใช้ OrderByKey() เพื่อจัดเรียงข้อมูล ระบบจะแสดงข้อมูลตามลำดับจากน้อยไปมาก ตามคีย์

  1. เด็กที่มีคีย์ที่แยกวิเคราะห์เป็นจำนวนเต็ม 32 บิตได้จะแสดงก่อน โดยเรียงตามลำดับจากน้อยไปมาก
  2. จากนั้นจะเป็นเด็กที่มีค่าสตริงเป็นคีย์ โดยจะจัดเรียงตามลำดับแบบพจนานุกรมจากน้อยไปมาก

OrderByValue

เมื่อใช้ OrderByValue() ระบบจะจัดเรียงเด็กตามมูลค่า เกณฑ์การจัดเรียง จะเหมือนกับใน OrderByChild() ยกเว้นจะใช้ค่าของโหนดแทนค่าของคีย์ย่อยที่ระบุ

ขั้นตอนถัดไป