JavaScript
TypeScript
Firebase
FirebaseCloudFunctions
Firestore

Firestoreのデータをasync/await, mapで取り出したい

環境

  • Cloud Functions
  • TypeScript

課題

https://firebase.google.com/docs/firestore/query-data/get-data

Collectionの中のDocumentをまとめて取得したい場合、公式ドキュメントに沿って実装すると、

index.ts
import * as functions from 'firebase-functions';
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

const db = admin.firestore();

export const getUserData = functions.https.onRequest((request, response) => {
  let data = [];
  db.collection('users').get().then(snapShot => {
    snapShot.forEach(doc => {
      data.push(doc.data());
    });
  }
  response.send({ data: data });
});

こんな感じになる。
これをasync/awaitとmapを使った実装に書き換えたい。

thenをasync/awaitに

index.ts
// 引数の前にasyncを付ける
export const getUserData = functions.https.onRequest(async (request, response) => {
  let data = [];
  const snapShot = await db.collection('users').get();
  snapShot.forEach(doc => {
    data.push(doc.data());
  })
  response.send({ data: data });
});

forEachをmapに

最初、次のような実装をした。

index.ts
export const getData = functions.https.onRequest(async (request, response) => {
  const snapShot = await db.collection('users').get();
  const data = snapShot.map(doc => {
    return doc.data();
  });
  response.send({ data: data });
});

が、APIを叩くとエラーが返ってくる。

Error: could not handle the request

ググったら解決策を発見。

https://stackoverflow.com/questions/46614055/map-items-of-collection-snapshot-in-firebase-firestore

要は docs プロパティを map してあげればいいらしい。

index.ts
export const getData = functions.https.onRequest(async (request, response) => {
  const snapShot = await db.collection('users').get();
  // docsをmapする
  const data = snapShot.docs.map(doc => {
    return doc.data();
  });
  response.send({ data: data });
});

無事、やりたい実装に到達。