LoginSignup
13
9

More than 3 years have passed since last update.

Firestore APIでのデータ取得に関わる主なクラスの関係図

Last updated at Posted at 2019-05-25

FirebaseをJavaScriptで触ってみているが、DBであるFirestoreからデータを取得する段階で何のメソッドを使えば何が返るのかよくわからず苦労している。そこで、基本的なクラスやメソッドに絞って互いの関係を図にしてみた。

図にしてみたら大して複雑ではなかったが、メソッドなのかプロパティなのかといった微妙な違いはまだ間違えそうなので、清書して残しておく。


なお、私はFirebaseを触るには以下の通り非常にスキルが低い。

  • 生のJavaScriptは多少扱えるが、フレームワークやトランスパイラなどは全くわからない
  • 非同期処理を扱ったことが無く、 Promise は今回初めて知った
  • さらにNoSQLも初めてで、どのようなデータ構造が良いか模索中
    • ドキュメント内にコレクションを持たせたり、フィールドのデータ型にreferenceを使ったり

文字数を減らすため記号による表現を多くしている。次節の「見方」を参照。

firestore-object-relations.png

見方

  • 角丸四角形はクラスを表す
    • 入れ子になっているものは、内側が基本クラスで外側が派生クラス
      • 派生クラスから基本クラスのプロパティやメソッドを呼べる
      • オーバーライドは図にしていない
  • 矢印はプロパティやメソッドを表す
    • 矢尻付近の文字列はその名前と付加情報
      • () 無しはプロパティ、ありはメソッド
      • {} ありは戻り値の型が Promise<T>
      • [] ありは戻り値の型が T[]
      • [field] はフィールドの値の参照(そのうちのreferenceデータ型のみを図示)
    • 戻り値が nullundefined である可能性は省略
    • 白い矢印は単に逆方向の参照が可能というだけ
  • 上下、左右は繋がっている
    • 左右方向は、ドキュメント内にコレクションを持てるということ
    • 上下方向は、フィールドのデータ型にreferenceが使えるということ

補足説明

図で省略したことや読み取りにくいことについて補足する。具体的な説明用のコードは、公式ドキュメントのサンプルを基にした。

Firestore からのreference取得

煩雑になるので図では省略したが、実際にコードを書くときは Firestore のインスタンスが起点となる。ここからコレクションやドキュメントを取得して初めて図示した関係を使えるようになる。

Firestore はメソッドとして collection()doc() の両方を持つので、コレクションとドキュメントのどちらのreferenceも取得できる1,2

// firebase初期化後、Firestoreのインスタンスを取得する
firebase.initializeApp(params);
const db = firebase.firestore();

// citiesコレクションのreferenceを取得する
let citiesRef = db.collection("cities");

クエリの設定と実行

Query のところに where() のループが描いてある。これは、クエリ用メソッドを繋げられることを示している。クエリを設定し終わったら(0個も可)、 get() を呼び出すことでクエリの結果である QuerySnapshot を得られる。

db.collection("cities")
        .where("state", "==", "CA")
        .where("population", ">", 1000000)
        .get().then((querySnapshot) => {...});

クエリは where() 以外にも orderBy(), limit(), startAt() などがある。 → クエリカーソルを使用したデータのページ設定

DocumentSnapshot の取得

ドキュメントのデータを得るには DocumentSnapshot を得る必要がある。図の矢印が示すように2通りの方法がある。

ひとつは DocumentReference から直接 get() する方法。ドキュメントが実際には存在しなくても取得されるが、その場合は data()undefined を返す。( data() を呼ばなくても exists で存在確認できる)

もうひとつは QuerySnapshotdocs を参照する方法3。クエリに該当したドキュメント全てが得られるため配列となっている。また、派生クラスが得られるが、これは data()undefined を返さないことが保証されている点のみ異なる。

// 単一のドキュメントの内容を取得する
db.collection("cities").doc("SF").get().then((doc) => {
    if (doc.exists) {
        console.log("Document data: ", doc.data());
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
});

// コレクション内のすべてのドキュメントを取得する
db.collection("cities").get().then((querySnapshot) => {
    querySnapshot.docs.forEach((doc) => {
        // doc.data() is never undefined for query doc snapshots
        console.log(doc.id, " => ", doc.data());
    });
});

フィールドの値の取得

data() が返す DocumentData は、全てのフィールドをキーに持つ普通のオブジェクト。

特定のフィールドの値のみ欲しい場合は、 DocumentSnapshotget() を使うことで DocumentData の取得をスキップできる。

データ型には様々なものがサポートされている。そのうちreferenceは図に描いた通り DocumentReference を指す。

参考

Firebase公式ドキュメントより


  1. 他に collectionGroup() でクエリ取得もできる。 

  2. 逆にreferenceやクエリから Firestore 取得もできる。プロパティ firestore を使う。 

  3. forEach() もあるので、ループを回すだけなら docs を挟まなくてもいい。 

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9