Firebase - Firestore
API
データの追加と管理
データモデル
ドキュメント
一つの JSON データ。 なお、ドキュメント内のネストされた Object のことを「マップ」という
コレクション
ドキュメントのコンテナ。自動で作成・削除される。
リファレンス
ドキュメントへのリファレンス
db.collection('users').doc('alovelace');
db.doc('users/alovelace');
コレクション へのリファレンス
db.collection('users');
サブコレクション内へのリファレンス
db.collection('rooms')
.document('roomA')
.collection('messages')
.document('message1');
データ構造の選択
子データ群をどのようにもつか
- 単純にネストさせる
- 簡単
- ネストされたリストにはクエリを実行できない
- ドキュメントが大きくなりがち
- サブコレクションを使う
- 親ドキュメントのサイズが変わらない
- クエリが使える(複数のサブコレクション間は不可)
- サブコレクションの削除が面倒
- ルートレベルのコレクションを使う
- クエリが強力
データの追加
db への参照を取得
const db = firebase.firestore();
更新
set
を使う。merge
オプションをつけると、既存データにマージされる。ないと、まるごと上書きされるので注意する。
db.doc('users/someSpecificId').set(
{
name: 'Ada',
},
{ merge: true },
);
一部の更新
ドキュメント全体を上書きせずにドキュメントの一部のフィールドを更新するには、update()
メソッドを使用する。
db.collection('cities')
.doc('DC')
.update({
capital: true,
favorites: { color: 'Blue' },
// なお、上記は下記のように書くこともできる
'favorites.color': 'Red',
// 更新日時を記録しておく方法
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
新規追加
set
もしくはadd
を使う。
// ドキュメントのIDを自動生成する場合(どちらも等価)
db.collection('users').add({
name: 'Ada',
});
db.collection('users').doc().set({
name: 'Ada',
});
// ドキュメントのIDを指定する場合
db.doc('users/someSpecificId').set(
{
name: 'Ada',
},
{ merge: true },
);
set と update の違い
set
without merge will overwrite a document or create it if it doesn't exist yetset
with merge will update fields in the document or create it if it doesn't existsupdate
will update fields but will fail if the document doesn't exist
アトミックオペレーション
- トランザクション 「読み書き」をまとめて行う
- 一括書き込み 「書き込み」をまとめて行う
いずれも、最大 500 ドキュメントまで。
トランザクション
フィールドの値を、その現 行値またはその他のフィールドの値に基づいて更新する場合には、トランザクションが便利です。
get
,set
,update
,delete
などが使える。注意点は下記のとおり。
get
は、set
,update
,delete
の前に実行する必要があるget
したドキュメントが、トランザクション実行中に他者に編集された場合は、トランザクションはやり直しされる。- トランザクション関数の中でアプリケーションの状態を直接変更してはダメ(複数回実行されることがあるから)
- クライアントがオフラインの場合、トランザクションは失敗する
// Create a reference to the SF doc.
var sfDocRef = db.collection('cities').doc('SF');
sfDocRef.set({ population: 0 });
const result = await db.runTransaction(transaction => {
// This code may get re-run multiple times if there are conflicts.
const sfDoc = await transaction.get(sfDocRef);
var newPopulation = sfDoc.data().population + 1;
transaction.update(sfDocRef, { population: newPopulation });
return newPopulation;
});
// アプリケーションの状態変更は、トランザクション関数の完了後に行うこと!
console.log('newPopulation:', result);