TypeScript & React & Firebase で何かつくってみる7 Functions 4

前回の Functions の疑問が一つ解決したのでそれを書く.

トランザクションで複数のドキュメントを扱う

前回「トランザクションで複数のドキュメントにアクセスしたいときどうしたらよいかわからない」と書いたが, 答えは firebase ライブラリのソースコード内にあった.

firestore.d.ts

  export class Transaction {
		:
   /**
    * Retrieves multiple documents from Firestore. Holds a pessimistic lock on
    * all returned documents.
    *
    * The first argument is required and must be of type `DocumentReference`
    * followed by any additional `DocumentReference` documents. If used, the
    * optional `ReadOptions` must be the last argument.
    *
    * @param {Array.<DocumentReference|ReadOptions>} documentRefsOrReadOptions
    * The `DocumentReferences` to receive, followed by an optional field
    * mask.
    * @return A Promise that resolves with an array of resulting document
    * snapshots.
    */
   getAll<T>(...documentRefsOrReadOptions: Array<DocumentReference|ReadOptions>):
       Promise<Array<DocumentSnapshot<T>>>;

拡張子 .d.ts は, まぁ C言語で言えば ヘッダファイル のようなもんだと思えばいいだろう. 

Transaction クラスに getAll() という関数が定義されている. これを使うと複数のドキュメントを同時にロックして読み取りを行えるらしい. (と,ここに書いてある)

やってみた.

type Deck = {
 cards: Card[]
}
export const draw = functions.region('asia-northeast1').https.onRequest((request, response) => {
 const deckRef = fireStore.collection('fields').doc('deck');
 const handRef = fireStore.collection('fields').doc('hand');
 fireStore.runTransaction(transaction => {
   return transaction.getAll(deckRef, handRef).then((snapshot => {
     const deck = snapshot[0].data() as Deck;
     const hand = snapshot[1].data() as Deck;
     if (deck.cards.length > 0) {
       hand.cards.push(deck.cards[0]);
       deck.cards.shift();
       transaction.update(deckRef, deck);
       transaction.update(handRef, hand);
     }
   }));
 }).then(snapshot => {
   response.send('success');
 }).catch(err => {
   response.status(404).send('not found');
 });
});

思ったとおりに動くことは確認した. ただ本当にアトミックに行われてるのかはわからん.

これ TypeScript でなかったらこんなにスムーズに解決しなかったかも. 静的型付けバンザイ.

そろそろ Firestore を学ぶ必要がでてきた

正直ここまで コレクションとドキュメントの違いもフワッとしたまま進めてきたが, そろそろちゃんと調べたほうがよさそうだ.


すばらしい記事を書く人たちがよく「まず公式を読め. 急がば回れだ.」というのだが, どうも私の性には合わない.

彼らはきっと頭がすごく良いのだろう. 私などが最初に公式を読もうものならその 圧倒的物量話の回りくどさ にたちまち 脳内メモリアロケーションエラーが発生する.

話の回りくどさは「丁寧さ」の裏返しで悪いことではない. しかし小さな脳内メモリをなんとかやりくりしてるような凡人エンジニアには, 必要最低メモリ容量が大きすぎる.

私は, 公式などの詳細ドキュメントを読む前に以下のようなことを行う.

1. 初心者向けの記事をいくつも 読む.  (複数記事を比較して偏りを調整する)
2. 初心者向けサンプルコードを動かす
3. サンプルコードを改変してみる. わからないところだけピンポイントで調べる.

これにより, その分野の知識の一部が二次記憶装置に書き込まれる. (つまり記憶が定着する.)
すると公式を読むときに必要なメモリを減らすことができる.

これが私にとっての 急がば回れ だ.


この記事が気に入ったらサポートをしてみませんか?