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

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

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

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

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

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

รับ 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 ครั้ง สำหรับบุตรหลานที่มีอยู่แต่ละคน แล้วเรียกใช้อีกครั้งทุกครั้งที่มีการเพิ่มบุตรหลานใหม่ไปยัง เส้นทางที่ระบุ ระบบจะส่งสแนปชอตที่มีข้อมูลขององค์ประกอบย่อยใหม่ให้ Listener

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

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

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

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

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

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

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

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

คุณรวมฟังก์ชัน 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. สตริงจะอยู่หลังตัวเลขและจัดเรียงตามลำดับตัวอักษรจากน้อยไปมาก หากบุตรหลานหลายคนมีค่าเดียวกันสำหรับโหนด child ที่ระบุ ระบบจะจัดเรียงตามพจนานุกรมตามคีย์
  6. ออบเจ็กต์จะอยู่ท้ายสุดและจัดเรียงตามพจนานุกรมตามคีย์จากน้อยไปมาก

OrderByKey

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

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

OrderByValue

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

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