รับการอ้างอิงฐานข้อมูล
หากต้องการอ่านหรือเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ 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 |
ดึงข้อมูลรายการสิ่งของหรือฟังการเพิ่มสิ่งของลงในรายการ ระบบจะทริกเกอร์เหตุการณ์นี้ 1 ครั้งสำหรับรายการย่อยที่มีอยู่แต่ละรายการ แล้วทริกเกอร์อีกครั้งทุกครั้งที่มีการเพิ่มรายการย่อยใหม่ลงในเส้นทางที่ระบุ ระบบจะส่งภาพรวมที่มีข้อมูลของบุตรหลานคนใหม่ให้ Listener |
onChildChanged |
ฟังการเปลี่ยนแปลงของรายการในลิสต์ เหตุการณ์นี้จะทริกเกอร์ทุกครั้งที่มีการแก้ไขโหนดย่อย ซึ่งรวมถึงการแก้ไขโหนดสืบทอดของโหนดบุตรหลาน สแนปชอตที่ส่งไปยัง Listener เหตุการณ์จะมีข้อมูลที่อัปเดตสำหรับรายการย่อย |
onChildRemoved |
ฟังรายการที่ถูกนำออกจากลิสต์ เหตุการณ์นี้จะทริกเกอร์เมื่อมีการนำรายการย่อยที่อยู่ติดกันออก สแนปชอตที่ส่งไปยังบล็อก Callback จะมีข้อมูลของรายการย่อยที่ถูกนำออก |
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.
});
ฟังเหตุการณ์ค่า
แม้ว่าการรอรับเหตุการณ์ย่อยจะเป็นวิธีที่แนะนำในการอ่านรายการข้อมูล แต่ก็มีบางสถานการณ์ที่การรอรับเหตุการณ์ค่าในการอ้างอิงรายการมีประโยชน์
การแนบ Listener value กับรายการข้อมูลจะแสดงรายการข้อมูลทั้งหมดเป็นสแนปชอตเดียว ซึ่งคุณสามารถวนซ้ำเพื่อเข้าถึงรายการย่อยแต่ละรายการได้
แม้ว่าจะมีรายการที่ตรงกันเพียงรายการเดียวสำหรับคำค้นหา แต่ภาพรวมก็ยังคงเป็นรายการที่มีเพียงรายการเดียว หากต้องการเข้าถึงรายการ คุณต้องวนซ้ำผลลัพธ์ดังนี้
myTopPostsQuery.onValue.listen((event) {
for (final child in event.snapshot.children) {
// Handle the post.
}
}, onError: (error) {
// Error.
});
รูปแบบนี้จะมีประโยชน์เมื่อคุณต้องการดึงข้อมูลรายการย่อยทั้งหมดของรายการในการดำเนินการเดียว แทนที่จะคอยฟังเหตุการณ์การเพิ่มรายการย่อยเพิ่มเติม
การจัดเรียงและการกรองข้อมูล
คุณสามารถใช้คลาส Query เพื่อดึงข้อมูลที่จัดเรียงตามคีย์ ตามค่า หรือตามค่าของรายการย่อยได้ นอกจากนี้ คุณยังกรองผลลัพธ์ที่จัดเรียงแล้วให้แสดงผลลัพธ์ตามจำนวนที่ต้องการ หรือแสดงคีย์หรือค่าตามช่วงที่ต้องการได้ด้วย
จัดเรียงข้อมูล
หากต้องการดึงข้อมูลที่จัดเรียงแล้ว ให้เริ่มด้วยการระบุเมธอดการจัดเรียงลำดับวิธีใดวิธีหนึ่งเพื่อกำหนดวิธีจัดเรียงผลลัพธ์ ดังนี้
| วิธีการ | การใช้งาน |
|---|---|
orderByChild() |
จัดเรียงผลลัพธ์ตามค่าของคีย์ย่อยที่ระบุหรือเส้นทางย่อยที่ซ้อนกัน |
orderByKey() |
จัดเรียงผลลัพธ์ตามคีย์ย่อย |
orderByValue() |
จัดเรียงผลลัพธ์ตามค่าของรายการย่อย |
คุณใช้เมธอดการจัดเรียงลำดับได้ครั้งละ 1 เมธอดเท่านั้น การเรียกใช้เมธอดการจัดเรียงลำดับหลายครั้งในการค้นหาเดียวกันจะทำให้เกิดข้อผิดพลาด
ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลรายการโพสต์ยอดนิยมของผู้ใช้ที่จัดเรียงตามจำนวนดาว
final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
.ref("user-posts/$myUserId")
.orderByChild("starCount");
ซึ่งจะกำหนดการค้นหาที่เมื่อรวมกับ child listener จะซิงค์ไคลเอ็นต์กับโพสต์ของผู้ใช้จากเส้นทางในฐานข้อมูลตามรหัสผู้ใช้ โดยเรียงลำดับตามจำนวนดาวที่แต่ละโพสต์ได้รับ เทคนิคการใช้รหัสเป็นคีย์ดัชนีนี้เรียกว่าการกระจายข้อมูล คุณสามารถอ่านเพิ่มเติมได้ในจัดโครงสร้างฐานข้อมูล
การเรียกใช้เมธอด 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 โดยระบุ Relative Path ไปยังรายการย่อยที่ฝังอยู่ในการเรียก 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() ข้อมูลที่มีคีย์ย่อยที่ระบุจะเรียงลำดับดังนี้
- รายการย่อยที่มีค่า
nullสำหรับคีย์ย่อยที่ระบุจะแสดงก่อน - ตามด้วยรายการย่อยที่มีค่า
falseสำหรับคีย์ย่อยที่ระบุ หากโหนดบุตรหลายโหนดมีค่าเป็นfalseระบบจะจัดเรียงโหนดบุตรเหล่านั้นตามพจนานุกรมตามคีย์ - ตามด้วยรายการย่อยที่มีค่า
trueสำหรับคีย์ย่อยที่ระบุ หากองค์ประกอบย่อยหลายรายการมีค่าเป็นtrueระบบจะจัดเรียงตามพจนานุกรมตามคีย์ - ตามด้วยรายการย่อยที่มีค่าตัวเลข โดยจัดเรียงจากน้อยไปมาก หากโหนดย่อยหลายโหนดมีค่าตัวเลขเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามคีย์
- สตริงจะอยู่หลังตัวเลขและจัดเรียงตามพจนานุกรมจากน้อยไปมาก หากโหนดย่อยหลายโหนดมีค่าเดียวกันสำหรับโหนดย่อยที่ระบุ ระบบจะจัดเรียงตามพจนานุกรมตามคีย์
- ออบเจ็กต์จะอยู่ท้ายสุดและจัดเรียงตามพจนานุกรมตามคีย์จากน้อยไปมาก
orderByKey
เมื่อใช้ orderByKey() เพื่อจัดเรียงข้อมูล ระบบจะแสดงผลข้อมูลตามลำดับจากน้อยไปมากตามคีย์
- รายการย่อยที่มีคีย์ที่แยกวิเคราะห์เป็นจำนวนเต็ม 32 บิตได้จะแสดงก่อน โดยจัดเรียงตามลำดับจากน้อยไปมาก
- รายการย่อยที่มีค่าสตริงเป็นคีย์จะแสดงถัดไป โดยจัดเรียงตามพจนานุกรมจากน้อยไปมาก
orderByValue
เมื่อใช้ orderByValue() ระบบจะจัดเรียงองค์ประกอบย่อยตามค่าขององค์ประกอบ เกณฑ์การจัดลำดับจะเหมือนกับใน orderByChild() ยกเว้นว่าจะใช้ค่าของโหนดแทนค่าของคีย์ย่อยที่ระบุ
แยก Listener
ระบบจะนำ Callback ออกโดยเรียกใช้เมธอด off() ในการอ้างอิงฐานข้อมูล Firebase
คุณสามารถนำ Listener รายการเดียวออกได้โดยส่งเป็นพารามิเตอร์ไปยัง off()
การเรียกใช้ off() ในตำแหน่งที่ไม่มีอาร์กิวเมนต์จะนำ Listener ทั้งหมดในตำแหน่งนั้นออก
การเรียกใช้ off() ใน Listener ระดับบนสุดจะไม่นำ Listener ที่ลงทะเบียนไว้ในโหนดระดับล่างออกโดยอัตโนมัติ คุณต้องเรียกใช้ off() ใน Listener ระดับล่างด้วยเพื่อนำ Callback ออก