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

เอกสารนี้ครอบคลุมข้อมูลเบื้องต้นเกี่ยวกับการดึงข้อมูล รวมถึงวิธีจัดเรียงและกรองข้อมูล 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 ครั้งเมื่อมีการแนบ Listener และอีกครั้งทุกครั้งที่ข้อมูลรวมถึงเด็กด้วย มีการเปลี่ยนแปลง แคล็กแบ็กเหตุการณ์จะได้รับสแนปชอตที่มีข้อมูลทั้งหมดในตำแหน่งนั้น รวมถึงข้อมูลย่อย หากไม่มีข้อมูล สแนปชอตที่แสดงผลจะเป็น 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 จะทริกเกอร์เมื่อนำบุตรหลานโดยตรงออก โดยปกติแล้วจะใช้ร่วมกับ Callback ChildAdded และ 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" ในองค์ประกอบย่อยแต่ละรายการ ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่วิธีจัดเรียงข้อมูลการค้นหา

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

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

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