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

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

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

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

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

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

คุณใช้วิธีการจัดเรียงได้ครั้งละ 1 วิธีเท่านั้น การเรียกใช้เมธอด "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');

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

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

วิธีจัดเรียงข้อมูลการค้นหา

ส่วนนี้จะอธิบายวิธีจัดเรียงข้อมูลตามเมธอด order-by แต่ละรายการในคลาส 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 ย่อยด้วย ด้วยเพื่อนำ Callback ออก

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