Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細

Web上のデータのリストを操作する

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

データベース参照を取得する

データベースからデータを読み書きするには、 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()メソッドによって返された新しいデータへの参照を使用して、子の自動生成キーの値を取得したり、子のデータを設定したりできます。 push()参照の.keyプロパティには、自動生成されたキーが含まれています。

これらの自動生成されたキーを使用して、データ構造のフラット化を簡素化できます。詳細については、データ ファンアウトのを参照してください。

たとえば、 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アイテムのリストを取得するか、アイテムのリストへの追加をリッスンします。このイベントは、既存の子ごとに 1 回トリガーされ、指定されたパスに新しい子が追加されるたびに再度トリガーされます。リスナーには、新しい子のデータを含むスナップショットが渡されます。
child_changedリスト内の項目への変更をリッスンします。このイベントは、子ノードが変更されるたびにトリガーされます。これには、子ノードの子孫への変更が含まれます。イベント リスナーに渡されるスナップショットには、子の更新されたデータが含まれています。
child_removedリストから削除される項目をリッスンします。このイベントは、直接の子が削除されたときにトリガーされます。コールバック ブロックに渡されるスナップショットには、削除された子のデータが含まれています。
child_moved順序付きリスト内のアイテムの順序の変更をリッスンします。 child_movedイベントは、(現在の order-by メソッドに基づいて) アイテムの順序を変更する原因となった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オブザーバーをデータのリストにアタッチすると、データのリスト全体が単一のスナップショットとして返され、ループして個々の子にアクセスできます。

クエリに一致するものが 1 つしかない場合でも、スナップショットはリストのままです。単一のアイテムが含まれているだけです。アイテムにアクセスするには、結果をループする必要があります。

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

このパターンは、追加の子追加イベントをリッスンするのではなく、1 回の操作でリストのすべての子をフェッチする場合に役立ちます。

データのソートとフィルタリング

Realtime Database Queryクラスを使用して、キー、値、または子の値で並べ替えられたデータを取得できます。並べ替えられた結果を特定の数の結果またはキーまたは値の範囲にフィルター処理することもできます。

データの並べ替え

並べ替えられたデータを取得するには、次のいずれかの order-by メソッドを指定して、結果の並べ替え方法を決定することから始めます。

方法使用法
orderByChild()指定された子キーまたはネストされた子パスの値で結果を並べ替えます。
orderByKey()結果を子キーで並べ替えます。
orderByValue()結果を子の値で並べ替えます。

一度に使用できる order-by メソッドは1 つだけです。同じクエリで order-by メソッドを複数回呼び出すと、エラーがスローされます。

次の例は、星の数で並べ替えられたユーザーのトップ投稿のリストを取得する方法を示しています。

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 をインデックス キーとして使用するこの手法は、データ ファン アウトと呼ばれます。詳細については、データベースの構築 を参照してください

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

この場合、 orderByChild()呼び出しでネストされた子への相対パスを指定することで、 metricsキーの下にネストされた値でリスト要素を並べ替えることができます。

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

他のデータ型の順序付けの詳細については、クエリ データの順序付け方法を参照してください。

データのフィルタリング

データをフィルター処理するには、クエリを作成するときに limit メソッドまたは range メソッドを order-by メソッドと組み合わせることができます。

方法使用法
limitToFirst()結果の順序付きリストの先頭から返す項目の最大数を設定します。
limitToLast()結果の順序付けられたリストの最後から返される項目の最大数を設定します。
startAt()選択した order-by メソッドに応じて、指定されたキーまたは値以上のアイテムを返します。
startAfter()選択した order-by メソッドに応じて、指定されたキーまたは値より大きい項目を返します。
endAt()選択した order-by メソッドに応じて、指定されたキーまたは値以下のアイテムを返します。
endBefore()選択した order-by メソッドに応じて、指定されたキーまたは値よりも少ないアイテムを返します。
equalTo()選択した order-by メソッドに応じて、指定されたキーまたは値に等しいアイテムを返します。

order-by メソッドとは異なり、複数の limit または range 関数を組み合わせることができます。たとえば、 startAt() () メソッドとendAt()メソッドを組み合わせて、結果を指定した範囲の値に制限できます。

結果の数を制限する

limitToFirst()およびlimitToLast()メソッドを使用して、特定のイベントで同期する子の最大数を設定できます。たとえば、 limitToFirst()を使用して制限を 100 に設定すると、最初は最大 100 のchild_addedイベントしか受け取りません。 Firebase データベースに保存されているアイテムが 100 未満の場合、アイテムごとにchild_addedイベントが発生します。

アイテムが変更されると、クエリに入るアイテムのchild_removedイベントと、そこから脱落するアイテムのchild_addedイベントを受け取り、合計数が 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クラスの各 order-by メソッドによってデータがどのようにソートされるかについて説明します。

orderByChild

orderByChild()を使用すると、指定された子キーを含むデータは次のように並べられます。

  1. 指定された子キーのnull値を持つ子が最初に来ます。
  2. 指定された子キーの値がfalseの子が次に来ます。複数の子の値がfalseの場合、それらはキーによって辞書順にソートされます。
  3. 指定された子キーの値がtrueの子が次に来ます。複数の子の値がtrueの場合、それらは辞書式にキーでソートされます。
  4. 次に、数値を持つ子が昇順でソートされます。複数の子が指定された子ノードに対して同じ数値を持つ場合、それらはキーでソートされます。
  5. 文字列は数値の後に続き、辞書式に昇順にソートされます。指定された子ノードに対して複数の子が同じ値を持つ場合、それらはキーによって辞書順に並べられます。
  6. オブジェクトは最後に来て、キーの昇順で辞書式にソートされます。

orderByKey

orderByKey()を使用してデータをソートすると、データはキーの昇順で返されます。

  1. 32 ビット整数として解析できるキーを持つ子が最初に来て、昇順でソートされます。
  2. 次にキーとして文字列値を持つ子が来て、辞書式に昇順にソートされます。

orderByValue

orderByValue()を使用すると、子はその値によって並べ替えられます。指定された子キーの値の代わりにノードの値が使用されることを除いて、順序付け基準はorderByChild()と同じです。

リスナーを切り離す

Firebase データベース参照でoff()メソッドを呼び出すと、コールバックが削除されます。

パラメータとしてoff()に渡すことで、単一のリスナーを削除できます。その場所で引数なしでoff()を呼び出すと、その場所にあるすべてのリスナーが削除されます。

親リスナーでoff()を呼び出しても、その子ノードに登録されているリスナーは自動的に削除されません。コールバックを削除するには、すべての子リスナーでoff()も呼び出す必要があります。

次のステップ