รับการอ้างอิงฐานข้อมูล
หากต้องการอ่านหรือเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ firebase.database.Reference ดังนี้
Web
import { getDatabase } from "firebase/database"; const database = getDatabase();
Web
var database = firebase.database();
การอ่านและการเขียนรายการ
เพิ่มข้อมูลลงในรายการ
ใช้เมธอด push() เพื่อเพิ่มข้อมูลลงในรายการในแอปพลิเคชันแบบผู้ใช้หลายคน
เมธอด push() จะสร้างคีย์ที่ไม่ซ้ำกันทุกครั้งที่มีการเพิ่มรายการย่อยใหม่ลงในการอ้างอิง Firebase ที่ระบุ การใช้คีย์ที่สร้างขึ้นโดยอัตโนมัติเหล่านี้สำหรับองค์ประกอบใหม่แต่ละรายการในรายการจะช่วยให้ไคลเอ็นต์หลายรายการเพิ่มรายการย่อยลงในตำแหน่งเดียวกันได้พร้อมกันโดยไม่มีข้อขัดแย้งในการเขียน คีย์ที่ไม่ซ้ำกันที่สร้างโดย push() จะอิงตามการประทับเวลา ดังนั้นรายการในรายการจะเรียงตามลำดับเวลาโดยอัตโนมัติ
คุณสามารถใช้การอ้างอิงข้อมูลใหม่ที่เมธอด push() ส่งคืนเพื่อรับค่าคีย์ที่สร้างขึ้นโดยอัตโนมัติของรายการย่อย หรือตั้งค่าข้อมูลสำหรับรายการย่อย พร็อพเพอร์ตี้ .key ของการอ้างอิง push() จะมีคีย์ที่สร้างขึ้นโดยอัตโนมัติ
คุณสามารถใช้คีย์ที่สร้างขึ้นโดยอัตโนมัติเหล่านี้เพื่อลดความซับซ้อนในการทำให้โครงสร้างข้อมูลแบนราบ ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างการกระจายข้อมูล
ตัวอย่างเช่น คุณสามารถใช้ push() เพื่อเพิ่มโพสต์ใหม่ลงในรายการโพสต์ในแอปพลิเคชันโซเชียลได้ ดังนี้
Web
import { getDatabase, ref, push, set } from "firebase/database"; // Create a new post reference with an auto-generated id const db = getDatabase(); const postListRef = ref(db, 'posts'); const newPostRef = push(postListRef); set(newPostRef, { // ... });
Web
// Create a new post reference with an auto-generated id var postListRef = firebase.database().ref('posts'); var newPostRef = postListRef.push(); newPostRef.set({ // ... });
รอรับเหตุการณ์ย่อย
ระบบจะทริกเกอร์เหตุการณ์ย่อยเพื่อตอบสนองต่อการดำเนินการที่เฉพาะเจาะจงซึ่งเกิดขึ้นกับรายการย่อยของโหนดจากการดำเนินการต่างๆ เช่น การเพิ่มรายการย่อยใหม่ผ่านเมธอด push() หรือการอัปเดตรายการย่อยผ่านเมธอด update()
| เหตุการณ์ | การใช้งานทั่วไป |
|---|---|
child_added |
ดึงข้อมูลรายการหรือรอรับการเพิ่มลงในรายการ ระบบจะทริกเกอร์เหตุการณ์นี้ 1 ครั้งสำหรับรายการย่อยที่มีอยู่แต่ละรายการ แล้วทริกเกอร์อีกครั้ง ทุกครั้งที่มีการเพิ่มรายการย่อยใหม่ลงในเส้นทางที่ระบุ ระบบจะส่งสแนปช็อตที่มีข้อมูลของรายการย่อยใหม่ไปยัง Listener |
child_changed |
รอรับการเปลี่ยนแปลงรายการในรายการ ระบบจะทริกเกอร์เหตุการณ์นี้ทุกครั้งที่มีการแก้ไขโหนดรายการย่อย ซึ่งรวมถึง การแก้ไขรายการที่สืบทอดมาจากโหนดรายการย่อย สแนปช็อตที่ส่ง ไปยัง Listener เหตุการณ์จะมีข้อมูลที่อัปเดตของรายการย่อย |
child_removed |
รอรับการนำรายการออกจากรายการ ระบบจะทริกเกอร์เหตุการณ์นี้เมื่อ มีการนำรายการย่อยออก สแนปช็อตที่ส่งไปยังบล็อก Callback จะมีข้อมูลของรายการย่อยที่นำออก |
child_moved |
รอรับการเปลี่ยนแปลงลำดับของรายการในรายการที่เรียงลำดับ
child_moved เหตุการณ์จะเกิดขึ้นหลังเหตุการณ์
child_changed เสมอ ซึ่งเป็นเหตุการณ์ที่ทำให้ลำดับของรายการเปลี่ยนแปลง (ตามเมธอดการเรียงลำดับปัจจุบัน)
|
การใช้เหตุการณ์เหล่านี้ร่วมกันจะมีประโยชน์ในการรอรับการเปลี่ยนแปลงโหนดที่เฉพาะเจาะจงในฐานข้อมูล ตัวอย่างเช่น แอปโซเชียลบล็อกอาจใช้เมธอดเหล่านี้ร่วมกันเพื่อตรวจสอบกิจกรรมในความคิดเห็นของโพสต์ ดังที่แสดงด้านล่าง
Web
import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database"; const db = getDatabase(); const commentsRef = ref(db, 'post-comments/' + postId); onChildAdded(commentsRef, (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); onChildChanged(commentsRef, (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); onChildRemoved(commentsRef, (data) => { deleteComment(postElement, data.key); });
Web
var commentsRef = firebase.database().ref('post-comments/' + postId); commentsRef.on('child_added', (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_changed', (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_removed', (data) => { deleteComment(postElement, data.key); });
รอรับเหตุการณ์ค่า
แม้ว่าการรอรับเหตุการณ์ย่อยจะเป็นวิธีที่แนะนำในการอ่านรายการข้อมูล แต่ก็มีบางสถานการณ์ที่การรอรับเหตุการณ์ค่าในการอ้างอิงรายการจะมีประโยชน์
การแนบ Observer value กับรายการข้อมูลจะแสดงรายการข้อมูลทั้งหมดเป็นสแนปช็อตเดียว ซึ่งคุณสามารถวนซ้ำเพื่อเข้าถึงรายการย่อยแต่ละรายการได้
แม้ว่าจะมีผลการค้นหาที่ตรงกับคำค้นหาเพียงรายการเดียว แต่สแนปช็อตก็ยังคงเป็นรายการ ซึ่งมีเพียงรายการเดียว หากต้องการเข้าถึงรายการ คุณต้องวนซ้ำผลลัพธ์ ดังนี้
Web
import { getDatabase, ref, onValue } from "firebase/database"; const db = getDatabase(); const dbRef = ref(db, '/a/b/c'); onValue(dbRef, (snapshot) => { snapshot.forEach((childSnapshot) => { const childKey = childSnapshot.key; const childData = childSnapshot.val(); // ... }); }, { onlyOnce: true });
Web
ref.once('value', (snapshot) => { snapshot.forEach((childSnapshot) => { var childKey = childSnapshot.key; var childData = childSnapshot.val(); // ... }); });
รูปแบบนี้จะมีประโยชน์เมื่อคุณต้องการดึงข้อมูลรายการย่อยทั้งหมดของรายการในการดำเนินการเดียว แทนที่จะรอรับเหตุการณ์การเพิ่มรายการย่อยเพิ่มเติม
การจัดเรียงและการกรองข้อมูล
คุณสามารถใช้คลาส Realtime Database Query เพื่อดึงข้อมูลที่จัดเรียงตาม
คีย์ ตามค่า หรือตามค่าของรายการย่อย นอกจากนี้ คุณยังกรองผลการค้นหาที่จัดเรียงแล้วให้แสดงผลลัพธ์ตามจำนวนที่เฉพาะเจาะจง หรือตามช่วงคีย์หรือค่าที่ต้องการได้ด้วย
จัดเรียงข้อมูล
หากต้องการดึงข้อมูลที่จัดเรียงแล้ว ให้เริ่มต้นด้วยการระบุเมธอดการเรียงลำดับรายการใดรายการหนึ่งเพื่อกำหนดวิธีจัดเรียงผลลัพธ์
| เมธอด | การใช้งาน |
|---|---|
orderByChild() |
จัดเรียงผลลัพธ์ตามค่าของคีย์รายการย่อยที่ระบุหรือเส้นทางรายการย่อยที่ซ้อนกัน |
orderByKey()
| จัดเรียงผลลัพธ์ตามคีย์รายการย่อย |
orderByValue() |
จัดเรียงผลลัพธ์ตามค่ารายการย่อย |
คุณใช้เมธอดการเรียงลำดับรายการได้เพียงรายการเดียว ในแต่ละครั้ง การเรียกเมธอดการเรียงลำดับรายการหลายครั้งในการค้นหาเดียวกันจะทำให้เกิดข้อผิดพลาด
ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลรายการโพสต์ยอดนิยมของผู้ใช้ที่จัดเรียงตามจำนวนดาว
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; import { getAuth } from "firebase/auth"; const db = getDatabase(); const auth = getAuth(); const myUserId = auth.currentUser.uid; const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));
Web
var myUserId = firebase.auth().currentUser.uid; var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');
ตัวอย่างนี้กำหนดการค้นหาที่เมื่อรวมกับ 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 ได้โดยการระบุเส้นทางสัมพัทธ์ไปยังรายการย่อยที่ซ้อนกันในการเรียก orderByChild()
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; const db = getDatabase(); const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));
Web
var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดเรียงข้อมูลประเภทอื่นๆ ได้ที่ หัวข้อ วิธีจัดเรียงข้อมูลการค้นหา
การกรองข้อมูล
หากต้องการกรองข้อมูล คุณสามารถรวมเมธอดการจำกัดหรือเมธอดช่วงใดก็ได้กับเมธอดการเรียงลำดับรายการเมื่อสร้างการค้นหา
| เมธอด | การใช้งาน |
|---|---|
limitToFirst() |
กำหนดจำนวนรายการสูงสุดที่จะแสดงผลจากจุดเริ่มต้นของ รายการผลลัพธ์ที่จัดเรียงแล้ว |
limitToLast() |
กำหนดจำนวนรายการสูงสุดที่จะแสดงผลจากจุดสิ้นสุดของรายการผลลัพธ์ที่จัดเรียงแล้ว |
startAt() |
แสดงรายการที่มีค่ามากกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการเรียงลำดับรายการที่เลือก |
startAfter() |
แสดงรายการที่มีค่ามากกว่าคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการเรียงลำดับรายการที่เลือก |
endAt() |
แสดงรายการที่มีค่าน้อยกว่าหรือเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการเรียงลำดับรายการที่เลือก |
endBefore() |
แสดงรายการที่มีค่าน้อยกว่าคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับเมธอดการเรียงลำดับรายการที่เลือก |
equalTo() |
แสดงรายการที่มีค่าเท่ากับคีย์หรือค่าที่ระบุ ทั้งนี้ขึ้นอยู่กับ เมธอดการเรียงลำดับรายการที่เลือก |
คุณสามารถรวมฟังก์ชันการจำกัดหรือฟังก์ชันช่วงหลายรายการได้ ซึ่งแตกต่างจากเมธอดการเรียงลำดับรายการ
ตัวอย่างเช่น คุณสามารถรวมเมธอด startAt() และ endAt() เพื่อจำกัดผลลัพธ์ให้แสดงค่าในช่วงที่ระบุ
จำกัดจำนวนผลลัพธ์
คุณสามารถใช้เมธอด limitToFirst() และ limitToLast() เพื่อกำหนดจำนวนสูงสุดของรายการย่อยที่จะซิงค์สำหรับเหตุการณ์ที่กำหนด ตัวอย่างเช่น หากคุณใช้ limitToFirst() เพื่อกำหนดขีดจำกัดไว้ที่ 100 คุณจะได้รับเหตุการณ์ child_added ไม่เกิน 100 รายการในตอนแรก หากคุณเก็บรายการไว้ในฐานข้อมูล Firebase น้อยกว่า 100 รายการ ระบบจะทริกเกอร์เหตุการณ์ child_added สำหรับแต่ละรายการ
เมื่อรายการมีการเปลี่ยนแปลง คุณจะได้รับเหตุการณ์ child_added สำหรับรายการที่เข้าสู่การค้นหา และเหตุการณ์ child_removed สำหรับรายการที่ออกจากผลการค้นหา เพื่อให้จำนวนรวมยังคงอยู่ที่ 100 รายการ
ตัวอย่างต่อไปนี้แสดงวิธีที่แอปบล็อกตัวอย่างกำหนดการค้นหาเพื่อดึงข้อมูลรายการโพสต์ล่าสุด 100 รายการจากผู้ใช้ทั้งหมด
Web
import { getDatabase, ref, query, limitToLast } from "firebase/database"; const db = getDatabase(); const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));
Web
var recentPostsRef = firebase.database().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 รายการเดียวออกได้โดยส่ง Listener เป็นพารามิเตอร์ไปยัง off()
การเรียก off() ในตำแหน่งที่ไม่มีอาร์กิวเมนต์จะนำ Listener ทั้งหมดในตำแหน่งนั้นออก
การเรียก off() ใน Listener หลักจะไม่นำ Listener ที่ลงทะเบียนไว้ในโหนดรายการย่อยออกโดยอัตโนมัติ คุณต้องเรียก off() ใน Listener รายการย่อยด้วยเพื่อนำ Callback ออก