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

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

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

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

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 ขององค์กรย่อยด้วย เพื่อนำการเรียกกลับออก

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