Check out what’s new from Firebase at Google I/O 2022. Learn more

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

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

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

Web version 9

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web version 8

var database = firebase.database();

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

ผนวกเข้ากับรายการข้อมูล

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

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

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

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

Web version 9

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 version 8

// 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 version 9

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 version 8

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 version 9

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 version 8

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

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

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

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

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

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

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

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

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

Web version 9

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 version 8

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 version 9

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

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

Web version 8

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 รายการเท่านั้น หากคุณมีน้อยกว่า 100 รายการเก็บไว้ในฐานข้อมูล Firebase เหตุการณ์ child_added จะเริ่มทำงานสำหรับแต่ละรายการ

เมื่อรายการเปลี่ยนไป คุณจะได้รับเหตุการณ์ child_added สำหรับรายการที่ป้อนคิวรีและเหตุการณ์ child_removed สำหรับรายการที่เลื่อนออกจากรายการเพื่อให้จำนวนทั้งหมดอยู่ที่ 100

ตัวอย่างต่อไปนี้สาธิตวิธีที่แอปบล็อกตัวอย่างกำหนดแบบสอบถามเพื่อดึงรายการโพสต์ล่าสุด 100 รายการโดยผู้ใช้ทั้งหมด:

Web version 9

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

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

Web version 8

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() บนตัวฟังหลักจะไม่ลบผู้ฟังที่ลงทะเบียนในโหนดย่อยโดยอัตโนมัติ off() จะต้องถูกเรียกไปยังผู้ฟังเด็กทุกคนเพื่อลบการโทรกลับ

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