くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

いまさらFirebaseのCloud Firestoreに入門してみた

以前RealTimeDatabaseで簡単なアプリを作ったことがあるけど、
Firestoreにそろそろ入門せねばと、公式ドキュメントの内容を整理してみた。

とりあえず、チートシート的に使うために、公式ドキュメントのまとめだけ。

概要

まずは、公式の「Cloud Firestore」より。

ドキュメントベースのNoSQL。構成としては以下の3つ。

  1. Data ... 値
  2. Document ... 値(Data)に対応するフィールドをまとめたもの
  3. Collection ... Documentをまとめたもの。クエリを作成できる

あと、

  • 文字列や数値から複雑なネストオブジェクトなど、複数のデータタイプをサポート
  • ドキュメント内にサブコレクションを作成し、階層型データ構造を構築できます。

らしい。

refs.

基本操作

初期化

// Initalization
const admin = require('firebase-admin');
const functions = require('firebase-functions');

admin.initializeApp(functions.config().firebase);
var db = admin.firestore();

ref.

データ型

Cloud Firestore では、文字列、ブール値、日付、NULL、ネストされた配列、オブジェクトなど、さまざまなデータ型をドキュメントに書き込むことができます。 Cloud Firestore は、コードで使用する数字の種類に関係なく、常に倍精度として数値を保存します。

// Data Types
var data = {
  stringExample: 'Hello, World!',
  booleanExample: true,
  numberExample: 3.14159265,
  dateExample: new Date('December 10, 1815'),
  arrayExample: [5, true, 'hello'],
  nullExample: null,
  objectExample: {
    a: 5,
    b: true
  }
};

var setDoc = db.collection('data').doc('one').set(data);

ref.

更新

const data = {
  first: 'Ada',
  last: 'Lovelace',
  born: 1815
}

// create or update Document
var setDoc = db.collection('collection-name').doc('doc-name').set(data);

// marge update Document
var setWithOptions = db.collection('collection-name').doc('doc-name').set(data, { merge: true });

// create Document: generate Id
var addDoc = await db.collection('collection-name').add(data);

// partial update
var updateDoc = db.collection('collection-name').doc('doc-name').update({ born: 1900 });


// set Server TimeStamp
var FieldValue = require('firebase-admin').firestore.FieldValue;
var updateTimestamp = db.collection('collection-name').doc('doc-name').update({
    timestamp: FieldValue.serverTimestamp()
});

ref.

参照

// Read Document
var documentRef = await db.collection('collection-name').doc('doc-name').get();
var documentRef = await db.doc('collection-name/doc-name').get();

// Read Document[]
var collectionRef = await db.collection('collection-name').get();

// Read sub-Collection
var subCollectionRef = await db.collection('collection-name').doc('doc-name').collection('sub-collection-name').get();

ref.

複雑な参照

// Query
var collection = await db.collection('collection-name').get();
var snapshot = await collectionRef.where("field-name", "==", true).get();

// fetch All sub-Collection
var collections = await db.collection('collection-name').doc('doc-name').getCollections();

// And Query
var collection = await db.collection('collection-name')
                         .where("fieldA", "==", true)
                         .where("fieldV", "<", 10000)
                         .get();

// Order By & limit
var collection = await db.collection('collection-name').orderBy('fieldA').limit(3);
var collection = await db.collection('collection-name').orderBy('fieldA', 'desc');
var collection = await db.collection('collection-name').orderBy('fieldA', 'desc').orderBy('fieldB');


// Order By with Query
citiesRef.where('population', '>', 2500000).orderBy('population');

注意点

  • 等価演算子==)と範囲比較(<、<=、>、>=)を組み合わせる場合は、必ずカスタムインデックスを作成してください。
  • 範囲比較(<、<=、>、>=)は、1つのフィールドでのみ実行できます。
  • 範囲フィルタ(where)と orderBy を同じフィールドに使用する。一致しない場合は無効。

ref.

以上!!