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

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

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

Web Modular API

import { getDatabase } from "firebase/database";

const database = getDatabase();

API ที่ใช้เนมสเปซในเว็บ

var database = firebase.database();

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

ต่อท้ายรายการข้อมูล

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

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

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

ตัวอย่างเช่น คุณสามารถใช้ push() เพื่อเพิ่มโพสต์ใหม่ไปยังรายการโพสต์ในแอปพลิเคชันโซเชียล

Web Modular API

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, {
    // ...
});

API ที่ใช้เนมสเปซในเว็บ

// 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 Modular API

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

API ที่ใช้เนมสเปซในเว็บ

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 Modular API

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

API ที่ใช้เนมสเปซในเว็บ

ref.once('value', (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    // ...
  });
});

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

การจัดเรียงและกรองข้อมูล

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

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

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

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

คุณใช้วิธีสั่งซื้อได้ครั้งละ 1 วิธีเท่านั้น การเรียกใช้เมธอดตามลำดับ หลายครั้งในข้อความค้นหาเดียวกันทำให้เกิดข้อผิดพลาด

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

Web Modular API

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

API ที่ใช้เนมสเปซในเว็บ

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 Modular API

import { getDatabase, ref, query, orderByChild } from "firebase/database";

const db = getDatabase();
const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));

API ที่ใช้เนมสเปซในเว็บ

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 Modular API

import { getDatabase, ref, query, limitToLast } from "firebase/database";

const db = getDatabase();
const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));

API ที่ใช้เนมสเปซในเว็บ

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

ปลดผู้ฟังออก

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

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

การเรียกใช้ off() ใน Listener หลักไม่ได้เป็นการนำ Listener ที่ลงทะเบียนในโหนดย่อยออกโดยอัตโนมัติ และ off() ต้องมีการเรียกในผู้ฟังย่อยทั้งหมดด้วย เพื่อนำ Callback ออก

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