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

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

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

คุณต้องดำเนินการต่อไปนี้ก่อนจึงจะใช้ Realtime Database ได้

  • ลงทะเบียนโปรเจ็กต์ Unity และกำหนดค่าให้ใช้ Firebase

    • หากโปรเจ็กต์ Unity ใช้ Firebase อยู่แล้ว โปรเจ็กต์ดังกล่าวจะได้รับการลงทะเบียนและกําหนดค่าสําหรับ Firebase อยู่แล้ว

    • หากไม่มีโปรเจ็กต์ Unity คุณสามารถดาวน์โหลดแอปตัวอย่างได้

  • เพิ่ม Firebase Unity SDK (โดยเฉพาะ FirebaseDatabase.unitypackage) ลงในโปรเจ็กต์ Unity

โปรดทราบว่าการเพิ่ม Firebase ลงในโปรเจ็กต์ Unity เกี่ยวข้องกับงานทั้งในคอนโซล Firebase และในโปรเจ็กต์ Unity ที่เปิดอยู่ (เช่น คุณดาวน์โหลดไฟล์การกําหนดค่า Firebase จากคอนโซล แล้วย้ายไฟล์เหล่านั้นไปยังโปรเจ็กต์ Unity)

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

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

รับ DatabaseReference

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

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

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

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

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task =&gt {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

รอรับเหตุการณ์

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

เหตุการณ์ การใช้งานทั่วไป
ValueChanged อ่านและฟังการเปลี่ยนแปลงเนื้อหาทั้งหมดของเส้นทาง
ChildAdded เรียกข้อมูลรายการหรือฟังการเพิ่มเติมรายการ แนะนำให้ใช้กับ ChildChanged และ ChildRemoved เพื่อตรวจสอบการเปลี่ยนแปลงรายการ
ChildChanged ฟังการเปลี่ยนแปลงรายการในรายการ ใช้ร่วมกับ ChildAdded และ ChildRemoved เพื่อตรวจสอบการเปลี่ยนแปลงในรายการ
ChildRemoved ฟังรายการที่นําออกจากรายการ ใช้ร่วมกับ ChildAdded และ ChildChanged เพื่อตรวจสอบการเปลี่ยนแปลงในรายการ
ChildMoved ฟังการเปลี่ยนแปลงลําดับของรายการในรายการที่เรียงลําดับ เหตุการณ์ ChildMoved จะตามหลังเหตุการณ์ ChildChanged เสมอ ซึ่งทําให้ลําดับของรายการเปลี่ยนแปลง (ตามวิธีการเรียงลําดับปัจจุบัน)

เหตุการณ์ ValueChanged

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

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs มี DataSnapshot ที่มีข้อมูลในตำแหน่งที่ระบุในฐานข้อมูล ณ เวลาที่เกิดเหตุการณ์ การเรียกใช้ Value ในสแนปชอตจะแสดงผล Dictionary<string, object> ที่แสดงข้อมูล หากไม่มีข้อมูลในตำแหน่งนั้น การเรียกใช้ Value จะแสดงผลเป็น null

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

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

เหตุการณ์ย่อย

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

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

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

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

ระบบจะทริกเกอร์เหตุการณ์ ChildRemoved เมื่อนำบุตรหลานโดยตรงออก โดยปกติจะใช้ร่วมกับ ChildAdded และ callbacks ของ ChildChanged ภาพรวมที่ส่งไปยังการเรียกกลับเหตุการณ์จะมีข้อมูลของบุตรหลานที่นําออก

ระบบจะเรียกเหตุการณ์ ChildMoved ให้แสดงทุกครั้งที่เหตุการณ์ ChildChanged เกิดขึ้นจากการอัปเดตที่ทําให้ต้องจัดลําดับรายการย่อยใหม่ โดยจะใช้กับข้อมูลที่จัดเรียงด้วย OrderByChild หรือ OrderByValue

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

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

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

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

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

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

ตัวอย่างต่อไปนี้แสดงวิธีติดตามในตารางอันดับตามคะแนน

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

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

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

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

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

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

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

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

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

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

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

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

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

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

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