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

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

หากต้องการอ่านหรือเขียนข้อมูลจากฐานข้อมูล คุณต้องมีอินสแตนซ์ของ 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 ของคุณ

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

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

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