Menangani Daftar Data di Web

Mendapatkan referensi database

Untuk membaca atau menulis data dari database, Anda memerlukan instance firebase.database.Reference:

API modular web

import { getDatabase } from "firebase/database";

const database = getDatabase();

API dengan namespace web

var database = firebase.database();

Membaca dan menulis daftar

Menambahi daftar data

Gunakan metode push() untuk menambahkan data ke daftar dalam aplikasi multi-pengguna. Metode push() menghasilkan kunci unik setiap kali turunan baru ditambahkan ke referensi Firebase tertentu. Dengan menggunakan kunci yang dihasilkan secara otomatis untuk setiap elemen baru dalam daftar, beberapa klien dapat menambahkan turunan ke lokasi yang sama secara bersamaan tanpa ada konflik tulis. Kunci unik yang dihasilkan oleh push() didasarkan pada stempel waktu, sehingga item daftar akan otomatis diurutkan secara kronologis.

Anda dapat menggunakan referensi ke data baru yang ditampilkan oleh metode push() untuk mendapatkan nilai kunci turunan yang dihasilkan otomatis atau menetapkan data untuk turunan. Properti .key dari referensi push() berisi kunci yang dihasilkan secara otomatis.

Anda dapat menggunakan kunci yang dihasilkan secara otomatis ini untuk mempermudah perataan struktur data. Untuk mengetahui informasi lebih lanjut, lihat contoh fan-out data.

Misalnya, push() dapat digunakan untuk menambahkan postingan baru ke daftar postingan di aplikasi sosial:

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

API dengan namespace web

// Create a new post reference with an auto-generated id
var postListRef = firebase.database().ref('posts');
var newPostRef = postListRef.push();
newPostRef.set({
    // ...
});

Memproses peristiwa turunan

Peristiwa turunan dipicu sebagai respons terhadap operasi tertentu yang terjadi pada turunan node dari suatu operasi, seperti turunan baru yang ditambahkan melalui metode push() atau turunan yang diperbarui melalui metode update().

Peristiwa Penggunaan standar
child_added Mengambil daftar item atau memproses penambahan ke daftar item. Peristiwa ini dipicu satu kali untuk setiap turunan yang ada, dan dipicu lagi setiap kali ada turunan baru yang ditambahkan ke jalur yang ditentukan. Snapshot yang berisi data turunan baru akan diteruskan ke pemroses.
child_changed Memproses perubahan pada item dalam daftar. Peristiwa ini dipicu setiap kali node turunan diubah. Ini juga termasuk perubahan pada turunan node turunan. Snapshot yang diteruskan ke pemroses peristiwa berisi data turunan yang diperbarui.
child_removed Memproses item yang dihapus dari daftar. Peristiwa ini dipicu ketika suatu turunan langsung dihapus. Snapshot yang diteruskan ke blok callback berisi data turunan yang dihapus.
child_moved Memproses perubahan urutan item dalam daftar yang diurutkan. Peristiwa child_moved selalu mengikuti peristiwa child_changed, yang menyebabkan urutan item berubah (berdasarkan metode 'urutkan menurut' saat ini).

Secara bersama-sama, setiap metode ini dapat berguna untuk memproses perubahan terhadap node tertentu dalam database. Misalnya, aplikasi blogging sosial mungkin menggunakan metode ini secara bersamaan untuk memantau aktivitas dalam komentar suatu postingan, seperti terlihat di bawah ini:

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

API dengan namespace 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);
});

Memproses peristiwa nilai

Meskipun memproses peristiwa turunan adalah cara yang disarankan untuk membaca daftar data, terkadang memproses peristiwa nilai di referensi daftar dapat berguna.

Menyertakan observer value ke daftar data akan menampilkan keseluruhan daftar data sebagai snapshot tunggal, yang nantinya dapat di-loop untuk mengakses setiap turunan.

Meskipun jika hanya ada satu kueri yang cocok, snapshot tetap merupakan sebuah daftar yang, dalam hal ini, berisi hanya satu item. Untuk mengakses item tersebut, Anda harus melakukan loop hasilnya:

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

API dengan namespace web

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

Pola ini dapat bermanfaat ketika Anda ingin mengambil semua turunan daftar dalam satu operasi, bukannya memproses peristiwa penambahan turunan lain.

Mengurutkan dan memfilter data

Anda bisa menggunakan class Query Realtime Database untuk memperoleh data yang diurutkan berdasarkan kunci, nilai, atau nilai turunan. Anda juga dapat memfilter hasil pengurutan berdasarkan jumlah hasil tertentu atau berdasarkan rentang kunci atau nilai.

Mengurutkan data

Untuk mengambil data yang diurutkan, mulai dengan menentukan salah satu metode 'urutkan menurut' guna menentukan cara pengurutan hasil:

Metode Penggunaan
orderByChild() Mengurutkan hasil menurut nilai kunci turunan atau jalur turunan bertingkat yang ditentukan.
orderByKey() Mengurutkan hasil menurut kunci turunan.
orderByValue() Mengurutkan hasil menurut nilai turunan.

Anda hanya bisa menggunakan satu metode 'urutkan menurut' pada satu waktu. Memanggil metode 'urutkan menurut' beberapa kali dalam kueri yang sama akan menampilkan error.

Contoh berikut menunjukkan cara mengambil daftar postingan teratas milik pengguna yang diurutkan berdasarkan jumlah bintangnya:

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

API dengan namespace web

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

Contoh ini menentukan kueri yang, jika dikombinasikan dengan pemroses turunan, akan menyinkronkan klien dengan postingan pengguna dari jalur dalam database berdasarkan ID penggunanya, yang diurutkan menurut jumlah bintang yang diterima setiap postingan. Teknik penggunaan ID sebagai kunci indeks ini disebut fan-out data. Anda dapat membaca hal ini lebih lanjut di bagian Membuat Struktur Database.

Panggilan ke metode orderByChild() menentukan kunci turunan sebagai dasar pengurutan hasil. Dalam kasus ini, postingan diurutkan berdasarkan nilai turunan "starCount" masing-masing. Kueri juga dapat diurutkan berdasarkan turunan bertingkat, jika Anda memiliki data yang tampak seperti ini:

"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",
  }
},

Dalam kasus ini, kita dapat mengurutkan elemen daftar berdasarkan nilai bertingkat dalam kunci metrics dengan menentukan jalur relatif ke turunan bertingkat pada panggilan orderByChild().

API modular web

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

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

API dengan namespace web

var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');

Untuk informasi lebih lanjut mengenai metode pengurutan jenis data lainnya, lihat Metode pengurutan data kueri.

Memfilter data

Untuk memfilter data, Anda dapat menggabungkan salah satu metode batas atau rentang dengan metode 'urutkan menurut' ketika menyusun kueri.

Metode Penggunaan
limitToFirst() Menetapkan jumlah item maksimum untuk ditampilkan dari awal daftar hasil yang diurutkan.
limitToLast() Menetapkan jumlah item maksimum untuk ditampilkan dari akhir daftar hasil yang diurutkan.
startAt() Menampilkan item yang lebih besar dari atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
startAfter() Menampilkan item yang lebih besar dari kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
endAt() Menampilkan item yang lebih kecil dari atau sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
endBefore() Menampilkan item yang lebih kecil dari kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.
equalTo() Menampilkan item yang sama dengan kunci atau nilai yang ditentukan, tergantung metode 'urutkan menurut' yang dipilih.

Berbeda dengan metode 'urutkan menurut', Anda dapat menggabungkan beberapa fungsi batas atau rentang. Misalnya, Anda dapat menggabungkan metode startAt() dan endAt() untuk membatasi hasil pada rentang nilai tertentu.

Membatasi jumlah hasil

Anda dapat menggunakan metode limitToFirst() dan limitToLast() untuk menetapkan jumlah turunan maksimum yang akan disinkronkan untuk peristiwa tertentu. Misalnya, jika Anda menggunakan limitToFirst() untuk menetapkan batas 100, pada awalnya Anda hanya akan menerima hingga 100 peristiwa child_added. Jika kurang dari 100 item tersimpan dalam database Firebase, peristiwa child_added akan diaktifkan untuk setiap item.

Saat item berubah, Anda akan menerima peristiwa child_added untuk item yang masuk ke kueri dan peristiwa child_removed untuk item yang keluar dari kueri, sehingga jumlah totalnya tetap 100.

Contoh berikut menunjukkan cara aplikasi blogging menentukan kueri untuk mengambil daftar 100 postingan terbaru oleh semua pengguna:

API modular web

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

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

API dengan namespace web

var recentPostsRef = firebase.database().ref('posts').limitToLast(100);

Contoh ini hanya menetapkan kueri. Untuk dapat benar-benar menyinkronkan data, perlu ada pemroses yang terpasang.

Memfilter berdasarkan kunci atau nilai

Anda dapat menggunakan startAt(), startAfter(), endAt(), endBefore(), dan equalTo() untuk memilih titik awal, akhir, dan ekuivalensi yang arbitrer untuk kueri. Hal ini dapat bermanfaat untuk pengelompokan halaman data atau menemukan item dengan turunan yang memiliki nilai tertentu.

Cara pengurutan data kueri

Bagian ini menjelaskan cara pengurutan data menggunakan setiap metode 'urutkan menurut' di class Query.

orderByChild

Jika Anda menggunakan orderByChild(), data yang berisi kunci turunan yang ditentukan akan diurutkan sebagai berikut:

  1. Turunan yang memiliki nilai null untuk kunci turunan yang ditentukan akan muncul terlebih dahulu.
  2. Turunan yang memiliki nilai false untuk kunci turunan yang ditentukan akan muncul berikutnya. Jika beberapa turunan memiliki nilai false, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  3. Turunan yang memiliki nilai true untuk kunci turunan yang ditentukan akan muncul berikutnya. Jika beberapa turunan memiliki nilai true, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  4. Turunan dengan nilai numerik akan muncul berikutnya, dan diurutkan menaik. Jika beberapa turunan memiliki nilai numerik yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan menurut kunci.
  5. String muncul setelah angka, dan diurutkan secara leksikografis menaik. Jika beberapa turunan memiliki nilai yang sama untuk node turunan yang ditentukan, turunan tersebut akan diurutkan secara leksikografis menurut kunci.
  6. Objek akan muncul terakhir, dan diurutkan secara leksikografis menaik menurut kunci.

orderByKey

Data yang diurutkan menggunakan orderByKey() akan ditampilkan dalam urutan menaik menurut kunci.

  1. Turunan dengan kunci yang bisa diurai sebagai bilangan bulat 32-bit akan muncul terlebih dahulu, dan diurutkan menaik.
  2. Turunan dengan nilai string sebagai kuncinya akan muncul berikutnya, dan diurutkan secara leksikografis menaik.

orderByValue

Jika menggunakan orderByValue(), turunan akan diurutkan menurut nilainya. Kriteria urutan sama seperti di orderByChild(), tetapi yang digunakan adalah nilai node, bukan nilai kunci turunan yang ditentukan.

Melepas pemroses

Callback akan dihapus dengan memanggil metode off() pada referensi database Firebase.

Anda dapat menghapus sebuah pemroses dengan meneruskannya sebagai parameter ke off(). Memanggil off() pada lokasi tanpa argumen akan menghapus semua pemroses yang ada di lokasi tersebut.

Memanggil off() pada pemroses induk tidak akan otomatis menghapus pemroses yang terdaftar pada node turunannya. off() juga harus dipanggil pada pemroses turunan mana pun untuk menghapus callback.

Langkah berikutnya