[Firebase]collection, documentからデータを取得する基本的な方法4つ[Cloud Firestore]

Firebase関連の記事_collection, document からのデータ取得について

Cloud firestore の collection, document から javascript でデータを取得してみる

今回は、Webアプリ制作などの際、データの保存やその管理で大活躍してくれる Cloud firestore の、
collection, document から、javascript でデータを取得する方法について、
簡単にふれていきたいと思います。

1. まずは、documentからデータを取得する基本形、[get().then()]から

const myDocRef = firebase.database().ref(`recipes/recipe/`);
let mydata;
myDocRef.get().then((doc) => {
  if (doc.exists) {
    // document からデータを取得して値を変数 mydata に格納する例。
    mydata = doc.data();
  } else {
    // ドキュメントがなかった場合
  }
}).catch((error) => {
  // なんらかの理由でエラーになった場合を想定。ここに処理を書いておく
});

例えば、「お料理レシピのWebアプリ」を制作しているとします。
その、制作しているWebアプリで使う firestore 内に、

recipes(collection:料理レシピ全体を格納)/recipe(document:料理レシピが並んでいる階層)/field(個々の料理の情報を持っている階層)

という構造のデータがあったとして、
document である recipe が持つ、複数のフィールド(この例の場合だと、醤油大さじ1、砂糖大さじ1みたいなレシピの詳細情報が並ぶはず
を取得したい場合。

そんな場合に使える基本形です。
上記の例で言えば、制作しているお料理系のWebアプリがあったとして、
その料理詳細ページなどにおいて、使ったりできるかと思います。
なんらかの詳細ページというのは、階層的には子階層のページのはずで、
という事は、
表示させたい項目は明確に決まっているケースが多いと思います。
表示させたい項目が明確に決まっているのであれば、
すでに取得すべき目的の document も決まっているはずですので、
シンプルに document から情報を取得したい場合に使用できる基本の形だと思います。

この取得方法に関するFirestore公式ページ

こちらの、document に対して get().then() を使った取得方法が書かれている Firestore 公式ドキュメントはこちらです。
公式ページでは「メソッドを呼び出してデータを取得する」と書かれていますね。
また、この公式ドキュメントにも書いてある通り、 get().then() を使った取得方法は collection にも使用できます。

Cloud Firestore でデータを取得する

2. collectionから、 onSnapshot を使って、firestore の更新をリッスンしながら取得する方法( get().then() も使えます)

const db = firebase.firestore();

// collection 'recipes' を参照
const sampleColRef = db.collection('recipes');

// 配列を定義しておく
let myArray = [];

// 取得したdataの格納用
let dataValue;

sampleColRef.onSnapshot((snapshot) => {
  myArray = []; // 最初に空にしておく。ここでしか使わない場合など、場合によっては記述不要。
  snapshot.forEach((doc) => {
    dataValue = doc.data();
    myArray.push({
      key: doc.id,
      value: dataValue
    });
  });
});

こちらの例は、以前の記事でも紹介した形になりますが、
collection からデータを取得する例です。

recipes(collection:料理レシピ全体を格納)/recipe(document:料理レシピが並んでいる階層)/field(個々の料理の情報を持っている階層)

↑こういった構造のデータがあったとして、
recipes 全体をリッスンして、複数のdocumentを含めて取得する場合の例です。

例えば、料理レシピ詳細ページの上の階層に、
いろんな料理レシピが複数並んでいるような
リストのページがあったとします。
そういった場合には、こちらの取得方法が適していると思います。

この onSnapshot() を使用することによって、
変更を受け取るリスナーが起動して、いわば、リアルタイムに変更を反映させることが可能になります。
(実際は、アプリのデータがローカルで変更されると、スナップショットリスナーと呼ばれるものが起動して、
送信前にデータを受け取って、metadata.hasPendingWrites というデータ送信前のプロパティを持ち…と、
間に複数のアクションが起きているようですが、すごく雑に言うと、「リアルタイムに変更を反映させることができる」。
実際にユーザーとしてUI上で目に見えるのは、そんな感じです。

なお、collectionからデータを取得するのには、
最初にご紹介した
get().then() ももちろん使えます。)

onSnapshot() に関する公式ドキュメント

onSnapshot() についての Firestore 公式ページはこちらです。metadata.hasPendingWrites に関する記述もありますね。
Cloud Firestore でリアルタイム アップデートを入手する

3. 条件を指定して、それに合致するデータを取得する基本形。[ where() ]

const sampleColRef = db.collection('recipes').where('category', '==', 'beer');

↑こちらも以前の記事でも触れたかと思いますが、改めてご紹介します。
こちらの例は、

recipes(collection:料理レシピ全体を格納)/recipe(document:料理レシピが並んでいる階層)/field(個々の料理の情報を持っている階層)

という構造のデータがあったとして、
collection の document の中から、
category という field の値に
ビールに合うレシピ beer を持っている物のみを取得する参照(reference)の作り方になります。

先ほどの collection に対する参照(reference)の末尾に、
取得したい条件をwhere()で指定するだけです。

仮に、料理レシピが並ぶリストページがあったとして、
「ビールに合うレシピ」という絞り込みのボタンがあったとします。
それを押した場合の
リスト表示用のデータを、あらかじめ絞り込んで用意しておく、
といった使い方ができるわけです。

4. where() には、複数の条件が指定できる

この便利な where() ですが、
もちろん複数の条件での絞り込みにも対応しています。

const sampleColRef = db.collection('recipes').where('category', '==', 'beer').where('color', '==', 'brown');

複数の条件を指定する場合、上記のように
さらに where() でつなぐだけです。

つまり上記の例では、
「ビールに合って、なおかつ色が茶色い料理」
が絞り込めるわけですね。
たぶん肉料理ってことでしょうね…おいしそう。

where() で使用できる条件式

where() では、以下の式によって、
絞り込みの条件を指定することができます。とっても柔軟ですね。

  • A < B ...値未満
  • A <= B ...値以下
  • A == B ...値に等しい
  • A > B ...値より大きい
  • A >= B ...値以上
  • A != B ...値と等しくない
  • array-contains ... (配列を用いた条件式)
  • array-contains-any ... (配列を用いた条件式)
  • in ... (最大10個までの等値を結合)
  • not-in ... (最大10個までの不等値を結合)

※Firestore 公式ドキュメントからの一部抜粋。

where() に関する Firestore 公式ページ

where() に関する Firestore 公式ページはこちらです。where() で使用できる条件式についての記述もあります。
Cloud Firestore で単純なクエリと複合クエリを実行する

この記事のまとめ

今回は、Cloud Firestore の collection, document から、
データを取得する基本の方法についてご紹介しました。

こんな感じのイメージで、イケてるWebアプリを作りたいなぁ...」、
という想いが先行しすぎると、ついつい

このデータは collection として持たせるべきなのか、
このデータはその document として持たせるべきなのか、

それらから
どのメソッドで情報を取得すべきなのか、
そういうところが
煩雑になりがちかと思います。

そういった部分の、
Cloud Firestore からデータを取得する基本的な方法について
自分自身の頭の中を整理する意味でも、もう一度改めておさらいしてみました。

最近は Vue.js と Vuetify の記事が多めですが
Cloud Firestore に関する記事に対する内容も、
随時書いていきたいと思っています。

※この記事は、内容の品質向上を目的に、随時更新を行う場合があります。