การดึงข้อมูลด้วยฐานข้อมูล Firebase Realtime สำหรับ C ++

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

ก่อนที่คุณจะเริ่ม

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

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

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

รับการอ้างอิงฐานข้อมูล

ในการเขียนข้อมูลลงฐานข้อมูล คุณต้องมีอินสแตนซ์ของ 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 สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบข้อผิดพลาด และวิธีการพิจารณาว่าผลลัพธ์จะพร้อมเมื่อใด

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

คุณสามารถเพิ่มผู้ฟังเพื่อติดตามการเปลี่ยนแปลงข้อมูลได้:

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

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

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

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

คลาส ValueListener

คุณสามารถใช้การเรียกกลับ OnValueChanged เพื่อสมัครรับการเปลี่ยนแปลงเนื้อหาในเส้นทางที่กำหนด การโทรกลับนี้จะถูกทริกเกอร์หนึ่งครั้งเมื่อมีการแนบ 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<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);

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

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

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

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

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

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

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

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

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

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

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

  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() ส่งคืนสินค้าเท่ากับคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก

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

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