ทำงานกับรายการข้อมูล

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

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

DatabaseReference ref = FirebaseDatabase.instance.ref();

การอ่านและการเขียนรายการ

ผนวกเข้ากับรายการข้อมูล

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

คุณสามารถใช้การอ้างอิงไปยังข้อมูลใหม่ที่ส่งกลับโดยเมธอด push() เพื่อรับค่าของคีย์ที่สร้างอัตโนมัติของเด็กหรือตั้งค่าข้อมูลสำหรับเด็ก คุณสมบัติ .key ของการอ้างอิง push() มีคีย์ที่สร้างขึ้นโดยอัตโนมัติ

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

ตัวอย่างเช่น สามารถใช้ push() เพื่อเพิ่มโพสต์ใหม่ลงในรายการโพสต์ในแอปพลิเคชันโซเชียล:

DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
  // ...
});

ฟังกิจกรรมสำหรับเด็ก

เหตุการณ์ลูกจะถูกทริกเกอร์เพื่อตอบสนองต่อการดำเนินการเฉพาะที่เกิดขึ้นกับลูกของโหนดจากการดำเนินการ เช่น ลูกใหม่ที่เพิ่มผ่านเมธอด push() หรือลูกที่ได้รับการอัปเดตผ่าน update()

เหตุการณ์ การใช้งานทั่วไป
onChildAdded ดึงรายการของรายการหรือฟังการเพิ่มเติมในรายการของรายการ เหตุการณ์นี้จะถูกทริกเกอร์หนึ่งครั้งสำหรับเด็กที่มีอยู่แต่ละคน และอีกครั้งทุกครั้งที่มีการเพิ่มเด็กใหม่ลงในเส้นทางที่ระบุ ผู้ฟังจะถูกส่งผ่านสแน็ปช็อตที่มีข้อมูลของเด็กใหม่
onChildChanged ฟังการเปลี่ยนแปลงของรายการในรายการ เหตุการณ์นี้จะถูกทริกเกอร์ทุกครั้งที่มีการแก้ไขโหนดลูก ซึ่งรวมถึงการปรับเปลี่ยนใด ๆ กับการสืบทอดของโหนดลูก สแน็ปช็อตที่ส่งไปยังตัวฟังเหตุการณ์ประกอบด้วยข้อมูลที่อัปเดตสำหรับเด็ก
onChildRemoved ฟังรายการที่ถูกลบออกจากรายการ เหตุการณ์นี้จะถูกทริกเกอร์เมื่อมีการลบลูกทันที สแน็ปช็อตที่ส่งผ่านไปยังบล็อกการโทรกลับประกอบด้วยข้อมูลสำหรับเด็กที่ถูกลบ
onChildMoved ฟังการเปลี่ยนแปลงลำดับของรายการในรายการสั่งซื้อ เหตุการณ์ onChildMoved มักจะติดตามเหตุการณ์ onChildChanged ที่ทำให้ลำดับของรายการเปลี่ยนแปลง (ขึ้นอยู่กับวิธีเรียงลำดับตามปัจจุบันของคุณ)

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

final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
  // A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
  // A comment has changed; use the key to determine if we are displaying this
  // comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
  // A comment has been removed; use the key to determine if we are displaying
  // this comment and if so remove it.
});

รับฟังเหตุการณ์อันทรงคุณค่า

แม้ว่าการฟังเหตุการณ์ลูกเป็นวิธีที่แนะนำในการอ่านรายการข้อมูล แต่ก็มีสถานการณ์การฟังเหตุการณ์ค่าในการอ้างอิงรายการซึ่งมีประโยชน์

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

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

myTopPostsQuery.onValue.listen((event) {
  for (final child in event.snapshot.children) {
    // Handle the post.
  }
}, onError: (error) {
  // Error.
});

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

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

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

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

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

วิธี การใช้งาน
orderByChild() เรียงลำดับผลลัพธ์ตามค่าของคีย์ลูกที่ระบุหรือเส้นทางลูกที่ซ้อนกัน
orderByKey() เรียงลำดับผลลัพธ์ด้วยคีย์ลูก
orderByValue() เรียงลำดับผลลัพธ์ตามค่าลูก

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

ตัวอย่างต่อไปนี้สาธิตวิธีที่คุณสามารถดึงรายการโพสต์ยอดนิยมของผู้ใช้โดยจัดเรียงตามจำนวนดาว:

final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
    .ref("user-posts/$myUserId")
    .orderByChild("starCount");

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

การเรียกเมธอด orderByChild() ระบุคีย์ลูกเพื่อเรียงลำดับผลลัพธ์ตาม ในกรณีนี้ โพสต์จะถูกจัดเรียงตามค่าของรายการย่อย "starCount" ที่เกี่ยวข้อง การสืบค้นสามารถเรียงลำดับตามรายการย่อยที่ซ้อนกันได้ ในกรณีที่คุณมีข้อมูลที่มีลักษณะดังนี้:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

ในกรณีนี้ เราสามารถเรียงลำดับองค์ประกอบรายการของเราตามค่าที่ซ้อนอยู่ใต้ metrics โดยการระบุเส้นทางสัมพัทธ์ไปยังรายการย่อยที่ซ้อนกันในการเรียก orderByChild() ของเรา

final mostViewedPosts =
    FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการเรียงลำดับข้อมูลประเภทอื่นๆ โปรดดู วิธีการเรียงลำดับข้อมูลคิวรี

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

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

วิธี การใช้งาน
limitToFirst() ตั้งค่าจำนวนรายการสูงสุดที่จะส่งคืนจากจุดเริ่มต้นของรายการผลลัพธ์ที่เรียงลำดับ
limitToLast() ตั้งค่าจำนวนรายการสูงสุดที่จะส่งคืนจากจุดสิ้นสุดของรายการผลลัพธ์ที่เรียงลำดับ
startAt() ส่งคืนรายการที่มากกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก
startAfter() ส่งคืนรายการที่มากกว่าคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก
endAt() ส่งคืนรายการที่น้อยกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก
endBefore() ส่งคืนรายการที่น้อยกว่าคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก
equalTo() ส่งคืนสินค้าเท่ากับคีย์หรือค่าที่ระบุ ขึ้นอยู่กับวิธีการเรียงลำดับที่เลือก

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

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

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

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

ตัวอย่างต่อไปนี้สาธิตวิธีที่แอปบล็อกตัวอย่างกำหนดการสืบค้นเพื่อดึงรายการโพสต์ล่าสุด 100 รายการโดยผู้ใช้ทั้งหมด:

final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);

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

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

คุณสามารถใช้ startAt() , startAfter() , endAt() , endBefore() และ equalTo() เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดเทียบเท่าตามต้องการสำหรับการสืบค้น สิ่งนี้มีประโยชน์สำหรับการแบ่งหน้าข้อมูลหรือค้นหารายการที่มีรายการลูกที่มีค่าเฉพาะ

วิธีเรียงลำดับข้อมูลการสืบค้น

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

orderByChild

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

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

orderByKey

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

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

orderByValue

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

แยกผู้ฟังออก

การเรียกกลับจะถูกลบออกโดยการเรียกเมธอด off() ในการอ้างอิงฐานข้อมูล Firebase ของคุณ

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

การเรียก off() บน parent Listener จะไม่ลบ Listener ที่ลงทะเบียนบนโหนดลูกโดยอัตโนมัติ จะต้องเรียกใช้ off() บนผู้ฟังเด็กเพื่อลบการโทรกลับ

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