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

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

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

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

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

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

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

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

คุณสามารถใช้คีย์ที่สร้างขึ้นโดยอัตโนมัติเหล่านี้เพื่อลดความซับซ้อนในการแปลงโครงสร้างข้อมูลเป็นรูปแบบแบน ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างแฟนเอาต์ (Fan-Out) ข้อมูล

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

ฟังเหตุการณ์ค่า

แม้ว่าการรอรับเหตุการณ์ย่อยจะเป็นวิธีที่แนะนําในการอ่านรายการข้อมูล แต่ก็มีบางกรณีที่การรอรับเหตุการณ์ค่าในข้อมูลอ้างอิงรายการมีประโยชน์

การแนบออบเจ็กต์ 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 เพื่อดึงข้อมูลที่จัดเรียงตามคีย์ ตามค่า หรือตามค่าของรายการย่อยได้ นอกจากนี้ คุณยังกรอง ผลลัพธ์ที่จัดเรียงให้เหลือจำนวนผลลัพธ์ที่เฉพาะเจาะจงหรือช่วงของคีย์หรือ ค่าได้ด้วย

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

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

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

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

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

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');

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

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

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

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

orderByKey

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

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

orderByValue

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

ยกเลิกการเชื่อมต่อ Listener

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

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

การเรียกใช้ off() ใน Listener ขององค์กรระดับบนจะไม่ นำ Listener ที่ลงทะเบียนในโหนดขององค์กรย่อยออกโดยอัตโนมัติ ต้องเรียกใช้ off() ใน Listener ขององค์กรย่อยด้วย เพื่อนำการเรียกกลับออก

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