เอกสารนี้ครอบคลุมการทำงานกับรายการข้อมูลใน Firebase หากต้องการเรียนรู้ พื้นฐานของการอ่านและการเขียนข้อมูล Firebase โปรดดู อ่านและเขียนข้อมูลใน Android
รับ DatabaseReference
หากต้องการอ่านและเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ DatabaseReference ดังนี้
Kotlin
private lateinit var database: DatabaseReference // ... database = Firebase.database.reference
Java
private DatabaseReference mDatabase; // ... mDatabase = FirebaseDatabase.getInstance().getReference();
อ่านและเขียนรายการ
เพิ่มข้อมูลลงในรายการ
ใช้เมธอด push() เพื่อเพิ่มข้อมูลลงในรายการในแอปพลิเคชันแบบหลายผู้ใช้
เมธอด push() จะสร้างคีย์ที่ไม่ซ้ำกันทุกครั้งที่มีการเพิ่มรายการย่อยใหม่ลงในการอ้างอิง Firebase ที่ระบุ การใช้คีย์ที่สร้างขึ้นโดยอัตโนมัติเหล่านี้สำหรับองค์ประกอบใหม่แต่ละรายการในรายการจะช่วยให้ไคลเอ็นต์หลายรายการเพิ่มรายการย่อยลงในตำแหน่งเดียวกันได้พร้อมกันโดยไม่มีข้อขัดแย้งในการเขียน คีย์ที่ไม่ซ้ำกันที่สร้างขึ้นโดย push() จะอิงตามการประทับเวลา ดังนั้นรายการในรายการจะเรียงตามลำดับเวลาโดยอัตโนมัติ
คุณสามารถใช้การอ้างอิงข้อมูลใหม่ที่เมธอด push() ส่งคืนเพื่อรับค่าคีย์ที่สร้างขึ้นโดยอัตโนมัติของรายการย่อยหรือตั้งค่าข้อมูลสำหรับรายการย่อย การเรียก getKey() ในการอ้างอิง push() จะส่งคืนค่าคีย์ที่สร้างขึ้นโดยอัตโนมัติ
คุณสามารถใช้คีย์ที่สร้างขึ้นโดยอัตโนมัติเหล่านี้เพื่อลดความซับซ้อนในการทำให้โครงสร้างข้อมูลแบนราบ ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างการกระจายข้อมูล
รับฟังเหตุการณ์ของรายการย่อย
เมื่อทำงานกับรายการ แอปพลิเคชันของคุณควรรับฟังเหตุการณ์ของรายการย่อยแทนเหตุการณ์ค่าที่ใช้กับออบเจ็กต์เดียว
เหตุการณ์ของรายการย่อยจะทริกเกอร์เพื่อตอบสนองต่อการดำเนินการที่เฉพาะเจาะจงซึ่งเกิดขึ้นกับรายการย่อยของโหนดจากการดำเนินการต่างๆ เช่น การเพิ่มรายการย่อยใหม่ผ่านเมธอด push() หรือการอัปเดตรายการย่อยผ่านเมธอด updateChildren()
เหตุการณ์เหล่านี้ร่วมกันจะมีประโยชน์สำหรับการรับฟังการเปลี่ยนแปลงของโหนดที่เฉพาะเจาะจงในฐานข้อมูล
หากต้องการรับฟังเหตุการณ์ของรายการย่อยใน DatabaseReference ให้แนบ ChildEventListener ดังนี้
| การส่งแบบฟอร์ม | การเรียกกลับของเหตุการณ์ | การใช้งานทั่วไป |
|---|---|---|
ChildEventListener
| onChildAdded() |
ดึงข้อมูลรายการหรือรับฟังการเพิ่มข้อมูลลงในรายการ
การเรียกกลับนี้จะทริกเกอร์ 1 ครั้งสำหรับรายการย่อยที่มีอยู่แต่ละรายการ จากนั้นจะทริกเกอร์อีกครั้ง
ทุกครั้งที่มีการเพิ่มรายการย่อยใหม่ลงในเส้นทางที่ระบุ `DataSnapshot` ที่ส่งไปยังการส่งแบบฟอร์มจะมีข้อมูลของรายการย่อยใหม่
|
onChildChanged() |
รับฟังการเปลี่ยนแปลงของรายการในรายการ เหตุการณ์นี้จะเริ่มทำงานทุกครั้งที่มีการแก้ไขโหนดรายการย่อย รวมถึงการแก้ไขรายการย่อยของโหนดรายการย่อย DataSnapshot ที่ส่งไปยังการส่งแบบฟอร์มของเหตุการณ์
จะมีข้อมูลที่อัปเดตของรายการย่อย
|
|
onChildRemoved() |
รับฟังการนำรายการออกจากรายการ
ที่ส่งไปยังการเรียกกลับของเหตุการณ์จะมีข้อมูลของรายการย่อยที่นำออกDataSnapshot
|
|
onChildMoved() |
รับฟังการเปลี่ยนแปลงลำดับของรายการในรายการที่เรียงลำดับ
เหตุการณ์นี้จะทริกเกอร์ทุกครั้งที่ onChildChanged()
การเรียกกลับทริกเกอร์โดยการอัปเดตที่ทำให้มีการจัดลำดับรายการย่อยใหม่
เหตุการณ์นี้ใช้กับข้อมูลที่เรียงลำดับด้วย orderByChild หรือ orderByValue
|
ตัวอย่างเช่น แอปบล็อกโซเชียลอาจใช้วิธีการเหล่านี้ร่วมกันเพื่อตรวจสอบกิจกรรมในความคิดเห็นของโพสต์ ดังที่แสดงด้านล่าง
Kotlin
val childEventListener = object : ChildEventListener { override fun onChildAdded(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildAdded:" + dataSnapshot.key!!) // A new comment has been added, add it to the displayed list val comment = dataSnapshot.getValue<Comment>() // ... } override fun onChildChanged(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildChanged: ${dataSnapshot.key}") // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. val newComment = dataSnapshot.getValue<Comment>() val commentKey = dataSnapshot.key // ... } override fun onChildRemoved(dataSnapshot: DataSnapshot) { Log.d(TAG, "onChildRemoved:" + dataSnapshot.key!!) // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. val commentKey = dataSnapshot.key // ... } override fun onChildMoved(dataSnapshot: DataSnapshot, previousChildName: String?) { Log.d(TAG, "onChildMoved:" + dataSnapshot.key!!) // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. val movedComment = dataSnapshot.getValue<Comment>() val commentKey = dataSnapshot.key // ... } override fun onCancelled(databaseError: DatabaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException()) Toast.makeText( context, "Failed to load comments.", Toast.LENGTH_SHORT, ).show() } } databaseReference.addChildEventListener(childEventListener)
Java
ChildEventListener childEventListener = new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey()); // A new comment has been added, add it to the displayed list Comment comment = dataSnapshot.getValue(Comment.class); // ... } @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so displayed the changed comment. Comment newComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey()); // A comment has changed, use the key to determine if we are displaying this // comment and if so remove it. String commentKey = dataSnapshot.getKey(); // ... } @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey()); // A comment has changed position, use the key to determine if we are // displaying this comment and if so move it. Comment movedComment = dataSnapshot.getValue(Comment.class); String commentKey = dataSnapshot.getKey(); // ... } @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "postComments:onCancelled", databaseError.toException()); Toast.makeText(mContext, "Failed to load comments.", Toast.LENGTH_SHORT).show(); } }; databaseReference.addChildEventListener(childEventListener);
รับฟังเหตุการณ์ค่า
แม้ว่าการใช้ ChildEventListener จะเป็นวิธีที่แนะนำในการอ่านรายการข้อมูล แต่ก็มีบางสถานการณ์ที่การแนบ ValueEventListener กับการอ้างอิงรายการจะมีประโยชน์
การแนบ ValueEventListener กับรายการข้อมูลจะส่งคืนรายการข้อมูลทั้งหมดเป็น DataSnapshot รายการเดียว ซึ่งคุณสามารถวนซ้ำเพื่อเข้าถึงรายการย่อยแต่ละรายการได้
แม้ว่าจะมีผลการค้นหาเพียงรายการเดียว สแนปช็อตก็ยังคงเป็นรายการ เพียงแต่มีรายการเดียว หากต้องการเข้าถึงรายการ คุณต้องวนซ้ำผลลัพธ์ดังนี้
Kotlin
// My top posts by number of stars myTopPostsQuery.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { for (postSnapshot in dataSnapshot.children) { // TODO: handle the post } } override fun onCancelled(databaseError: DatabaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
รูปแบบนี้จะมีประโยชน์เมื่อคุณต้องการดึงข้อมูลรายการย่อยทั้งหมดของรายการในการดำเนินการเดียว แทนที่จะรับฟังเหตุการณ์ onChildAdded เพิ่มเติม
ยกเลิกการแนบการส่งแบบฟอร์ม
ระบบจะนำการเรียกกลับออกโดยการเรียกเมธอด removeEventListener() ในการอ้างอิงฐานข้อมูล Firebase
หากมีการเพิ่ม Listener ไปยังตำแหน่งข้อมูลหลายครั้ง ระบบจะเรียก Listener นั้นหลายครั้งสำหรับแต่ละเหตุการณ์ และคุณต้องปลดออก Listener จำนวนครั้งเท่ากันเพื่อนำ Listener ออกทั้งหมด
การเรียก removeEventListener() ในการส่งแบบฟอร์มระดับบนจะไม่นำการส่งแบบฟอร์มที่ลงทะเบียนในโหนดรายการย่อยออกโดยอัตโนมัติ คุณต้องเรียก removeEventListener() ในการส่งแบบฟอร์มของรายการย่อยด้วยเพื่อนำการเรียกกลับออก
การจัดเรียงและการกรองข้อมูล
คุณสามารถใช้คลาส Realtime Database Query เพื่อดึงข้อมูลที่จัดเรียงตาม
คีย์ ตามค่า หรือตามค่าของรายการย่อย นอกจากนี้ คุณยังกรองผลลัพธ์ที่จัดเรียงแล้วให้แสดงผลลัพธ์ตามจำนวนที่เฉพาะเจาะจงหรือช่วงของคีย์หรือค่าได้ด้วย
จัดเรียงข้อมูล
หากต้องการดึงข้อมูลที่จัดเรียงแล้ว ให้เริ่มต้นด้วยการระบุเมธอดการจัดเรียงตามรายการใดรายการหนึ่งเพื่อกำหนดวิธีจัดเรียงผลลัพธ์
| เมธอด | การใช้งาน |
|---|---|
orderByChild() |
จัดเรียงผลลัพธ์ตามค่าของคีย์รายการย่อยหรือเส้นทางรายการย่อยที่ซ้อนกันที่ระบุ |
orderByKey()
| จัดเรียงผลลัพธ์ตามคีย์รายการย่อย |
orderByValue() |
จัดเรียงผลลัพธ์ตามค่ารายการย่อย |
คุณใช้เมธอดการจัดเรียงตามรายการได้เพียงรายการเดียว ในแต่ละครั้ง การเรียกเมธอดการจัดเรียงตามรายการหลายครั้งในการค้นหาเดียวกันจะทำให้เกิดข้อผิดพลาด
ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลรายการโพสต์ยอดนิยมของผู้ใช้ที่จัดเรียงตามจำนวนดาว
Kotlin
// My top posts by number of stars val myUserId = uid val myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount") myTopPostsQuery.addChildEventListener(object : ChildEventListener { // TODO: implement the ChildEventListener methods as documented above // ... })
Java
// My top posts by number of stars String myUserId = getUid(); Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId) .orderByChild("starCount"); myTopPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
ตัวอย่างนี้กำหนดการค้นหาที่เมื่อรวมกับการส่งแบบฟอร์มของรายการย่อยแล้ว จะซิงค์ไคลเอ็นต์กับโพสต์ของผู้ใช้จากเส้นทางในฐานข้อมูลตามรหัสผู้ใช้ โดยจัดเรียงตามจำนวนดาวที่แต่ละโพสต์ได้รับ เทคนิคการใช้รหัสเป็นคีย์ดัชนีนี้เรียกว่าการกระจายข้อมูล คุณสามารถอ่าน ข้อมูลเพิ่มเติมเกี่ยวกับเทคนิคนี้ได้ใน หัวข้อการจัดโครงสร้างฐานข้อมูล
การเรียกเมธอด 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()
Kotlin
// Most viewed posts val myMostViewedPostsQuery = databaseReference.child("posts") .orderByChild("metrics/views") myMostViewedPostsQuery.addChildEventListener(object : ChildEventListener { // TODO: implement the ChildEventListener methods as documented above // ... })
Java
// Most viewed posts Query myMostViewedPostsQuery = databaseReference.child("posts") .orderByChild("metrics/views"); myMostViewedPostsQuery.addChildEventListener(new ChildEventListener() { // TODO: implement the ChildEventListener methods as documented above // ... });
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่ หัวข้อวิธีจัดเรียงข้อมูลการค้นหา
การกรองข้อมูล
หากต้องการกรองข้อมูล คุณสามารถรวมเมธอดการจำกัดหรือช่วงใดก็ได้กับเมธอดการจัดเรียงตามรายการเมื่อสร้างการค้นหา
| เมธอด | การใช้งาน |
|---|---|
limitToFirst() |
กำหนดจำนวนรายการสูงสุดที่จะแสดงจากจุดเริ่มต้นของ รายการผลลัพธ์ที่จัดเรียงแล้ว |
limitToLast() |
กำหนดจำนวนรายการสูงสุดที่จะแสดงจากจุดสิ้นสุดของรายการผลลัพธ์ที่จัดเรียงแล้ว |
startAt() |
แสดงรายการที่มีค่ามากกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการจัดเรียงตามรายการที่เลือก |
startAfter() |
แสดงรายการที่มีค่ามากกว่าคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการจัดเรียงตามรายการที่เลือก |
endAt() |
แสดงรายการที่มีค่าน้อยกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการจัดเรียงตามรายการที่เลือก |
endBefore() |
แสดงรายการที่มีค่าน้อยกว่าคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการจัดเรียงตามรายการที่เลือก |
equalTo() |
แสดงรายการที่มีค่าเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการจัดเรียงตามรายการที่เลือก |
คุณสามารถรวมฟังก์ชันการจำกัดหรือช่วงหลายรายการได้ ซึ่งแตกต่างจากเมธอดการจัดเรียงตามรายการ
ตัวอย่างเช่น คุณสามารถรวมเมธอด startAt() และ endAt() เพื่อจำกัดผลลัพธ์ให้อยู่ในช่วงค่าที่ระบุ
แม้ว่าจะมีผลการค้นหาเพียงรายการเดียว สแนปช็อตก็ยังคงเป็นรายการ เพียงแต่มีรายการเดียว หากต้องการเข้าถึงรายการ คุณต้องวนซ้ำผลลัพธ์ดังนี้
Kotlin
// My top posts by number of stars myTopPostsQuery.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { for (postSnapshot in dataSnapshot.children) { // TODO: handle the post } } override fun onCancelled(databaseError: DatabaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()) // ... } })
Java
// My top posts by number of stars myTopPostsQuery.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... } });
จำกัดจำนวนผลลัพธ์
คุณสามารถใช้เมธอด limitToFirst() และ limitToLast() เพื่อกำหนดจำนวนสูงสุดของรายการย่อยที่จะซิงค์สำหรับการเรียกกลับที่กำหนด ตัวอย่างเช่น หากคุณใช้ limitToFirst() เพื่อกำหนดขีดจำกัดไว้ที่ 100 คุณจะได้รับการเรียกกลับ onChildAdded() ไม่เกิน 100 รายการในตอนแรก หากคุณเก็บรายการไว้ในฐานข้อมูล Firebase น้อยกว่า 100 รายการ การเรียกกลับ onChildAdded() จะเริ่มทำงานสำหรับแต่ละรายการ
เมื่อรายการมีการเปลี่ยนแปลง คุณจะได้รับการเรียกกลับ onChildAdded() สำหรับรายการที่เข้าสู่การค้นหา และการเรียกกลับ onChildRemoved() สำหรับรายการที่ออกจากผลการค้นหา เพื่อให้จำนวนรวมยังคงอยู่ที่ 100 รายการ
ตัวอย่างต่อไปนี้แสดงวิธีที่แอปบล็อกตัวอย่างกำหนดการค้นหาเพื่อดึงข้อมูลรายการโพสต์ล่าสุด 100 รายการจากผู้ใช้ทั้งหมด
Kotlin
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys. databaseReference.child("posts").limitToFirst(100)
Java
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys Query recentPostsQuery = databaseReference.child("posts") .limitToFirst(100);
ตัวอย่างนี้กำหนดการค้นหาเท่านั้น หากต้องการซิงค์ข้อมูลจริง คุณต้อง แนบการส่งแบบฟอร์ม
กรองตามคีย์หรือค่า
คุณสามารถใช้ startAt(), startAfter(), endAt(), endBefore() และ equalTo() เพื่อเลือกจุดเริ่มต้น จุดสิ้นสุด และจุดเทียบเท่าที่กำหนดเองสำหรับการค้นหา ซึ่งอาจมีประโยชน์สำหรับการแบ่งหน้าข้อมูลหรือค้นหารายการที่มีรายการย่อยที่มีค่าที่เฉพาะเจาะจง
วิธีจัดเรียงข้อมูลการค้นหา
ส่วนนี้อธิบายวิธีจัดเรียงข้อมูลตามเมธอดการจัดเรียงตามรายการแต่ละรายการในคลาส Query
orderByChild
เมื่อใช้ orderByChild() ระบบจะจัดเรียงข้อมูลที่มีคีย์รายการย่อยที่ระบุดังนี้
- รายการย่อยที่มีค่า
nullสำหรับคีย์รายการย่อยที่ระบุจะแสดง ก่อน - รายการย่อยที่มีค่า
falseสำหรับคีย์รายการย่อยที่ระบุ จะแสดงถัดไป หากรายการย่อยหลายรายการมีค่าfalseระบบจะจัดเรียงรายการย่อยเหล่านั้น ตามลำดับพจนานุกรมตามคีย์ - รายการย่อยที่มีค่า
trueสำหรับคีย์รายการย่อยที่ระบุ จะแสดงถัดไป หากรายการย่อยหลายรายการมีค่าtrueระบบจะจัดเรียงรายการย่อยเหล่านั้น ตามลำดับพจนานุกรมตามคีย์ - รายการย่อยที่มีค่าเป็นตัวเลขจะแสดงถัดไป โดยจัดเรียงตามลำดับจากน้อยไปมาก หากรายการย่อยหลายรายการมีค่าตัวเลขเดียวกันสำหรับโหนดรายการย่อยที่ระบุ ระบบจะจัดเรียงรายการย่อยเหล่านั้นตามคีย์
- สตริงจะแสดงหลังตัวเลขและจัดเรียงตามลำดับพจนานุกรมจากน้อยไปมาก หากรายการย่อยหลายรายการมีค่าเดียวกันสำหรับโหนดรายการย่อยที่ระบุ ระบบจะจัดเรียงรายการย่อยเหล่านั้นตามลำดับพจนานุกรมตามคีย์
- ออบเจ็กต์จะแสดงเป็นรายการสุดท้ายและจัดเรียงตามลำดับพจนานุกรมตามคีย์จากน้อยไปมาก
orderByKey
เมื่อใช้ orderByKey() เพื่อจัดเรียงข้อมูล ระบบจะแสดงข้อมูลตามลำดับจากน้อยไปมากตามคีย์
- รายการย่อยที่มีคีย์ที่แยกวิเคราะห์เป็นจำนวนเต็ม 32 บิตได้จะแสดงก่อน โดยจัดเรียงตามลำดับจากน้อยไปมาก
- รายการย่อยที่มีค่าสตริงเป็นคีย์จะแสดงถัดไป โดยจัดเรียงตามลำดับพจนานุกรมจากน้อยไปมาก
orderByValue
เมื่อใช้ orderByValue() ระบบจะจัดเรียงรายการย่อยตามค่า เกณฑ์การจัดเรียงจะเหมือนกับใน orderByChild() ยกเว้นว่าจะใช้ค่าของโหนดแทนค่าของคีย์รายการย่อยที่ระบุ