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

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

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

Web modular API

import { getDatabase } from "firebase/database";

const database = getDatabase();

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

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

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

Web namespaced API

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

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

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

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

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

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

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

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

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

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

Web namespaced API

var myUserId = firebase.auth().currentUser.uid;
var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');

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

การเรียกเมธอด 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'));

Web namespaced 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));

Web namespaced 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() ในตำแหน่งที่ไม่มีข้อโต้แย้งจะเป็นการลบผู้ฟังทั้งหมดในตำแหน่งนั้น

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

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