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

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

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

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

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

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

รับ DatabaseReference

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

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

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

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

  firebase::Future<firebase::database::DataSnapshot> 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 callback จะตามหลังOnChildChanged callback เสมอเนื่องจากลําดับของรายการมีการเปลี่ยนแปลง (ตามวิธีการจัดเรียงปัจจุบัน)

คลาส ValueListener

คุณสามารถใช้ OnValueChanged callbacks เพื่อติดตามการเปลี่ยนแปลงเนื้อหาในเส้นทางที่ระบุ การเรียกกลับนี้จะทริกเกอร์ 1 ครั้งเมื่อมีการแนบตัวฟัง และอีกครั้งทุกครั้งที่มีการเปลี่ยนแปลงข้อมูล รวมถึงการเปลี่ยนแปลงของรายการย่อย ระบบจะส่งสแนปชอตที่มีข้อมูลทั้งหมดในตำแหน่งนั้น รวมถึงข้อมูลย่อย ไปยังการเรียกกลับ หากไม่มีข้อมูล สแนปชอตที่แสดงผลจะเป็น 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<firebase::database::DataSnapshot> 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<firebase::database::DataSnapshot> result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

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

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

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

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

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

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

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

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

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

คุณใช้วิธีการจัดเรียงได้ครั้งละ 1 วิธีเท่านั้น การเรียกใช้เมธอด "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" value ในแต่ละรายการย่อย ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่วิธีจัดเรียงข้อมูลการค้นหา

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

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

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

คุณรวมฟังก์ชันการจำกัดหรือช่วงหลายรายการเข้าด้วยกันได้ ซึ่งแตกต่างจากเมธอด 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() เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดที่เทียบเท่าแบบกำหนดเองสำหรับคำค้นหา ซึ่งจะมีประโยชน์สำหรับการแบ่งหน้าข้อมูลหรือค้นหารายการที่มีรายการย่อยซึ่งมีค่าที่เฉพาะเจาะจง

วิธีจัดเรียงข้อมูลการค้นหา

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

OrderByChild

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

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

OrderByKey

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

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

OrderByValue

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

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