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

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

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

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

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

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

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

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

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

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

ระบบจะดึงข้อมูล Firebase โดยการเรียก GetValueAsync() เพียงครั้งเดียว หรือแนบกับเหตุการณ์ในการอ้างอิง FirebaseDatabase ระบบจะเรียก Listener เหตุการณ์ 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...
        }
      });

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

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

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

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

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

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

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

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

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

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

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

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

ตัวอย่างต่อไปนี้แสดงให้เห็นว่าคุณจะสมัครรับข้อมูลลีดเดอร์บอร์ดคะแนนที่จัดลำดับตามคะแนนได้อย่างไร

      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
    }

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

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

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

หากต้องการกรองข้อมูล คุณสามารถรวมวิธีการจำกัดหรือวิธีการกำหนดช่วงใดก็ได้กับวิธีการจัดลำดับเมื่อสร้างการค้นหา

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

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

วิธีจัดลำดับข้อมูลการค้นหา

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

OrderByChild

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

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

OrderByKey

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

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

OrderByValue

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