Cloud Functions as a Frontend for Firestore

Web から Firestore を使うと、アクセスキーが開発ツールから丸見えになってしまうのが不安。いやまぁ、ちゃんとアクセスルールを設定すれば問題ないんだろうけど、自分の Firestore スキルはまだそこまでではない。うっかり設定し忘れもあり得る。

いっそ、Cloud Functions for Firebase で Web API を実装し、その中から Firestore にアクセスすれば、アクセスキーを覗かれずに済むんじゃないか?というわけでやってみた。

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as express from 'express';

const serviceAccount: admin.ServiceAccount = {
  "projectId": "FIrebase プロジェクト ID",
  "privateKey": "サービスアカウントに発行したアクセスキーの JSON の privateKey",
  "clientEmail": "サービスアカウントに発行したアクセスキーの JSON の clientEmail",
};

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
});

const db = admin.firestore();

const app = express();

app.get('/items', async (req, res) => {
    const snapshot = await db.collection('items')
        .orderBy('createdAt', 'desc')
        .get();

    const items = [];
    snapshot.forEach((doc) => {
        const item = doc.data();
        items.push(item);
    });

    res.writeHead(200, {
        'Content-Type': 'application/json',
    });
    res.send(JSON.stringify(items));
});

app.get('/items/:id', async (req, res) => {
    const id = req.param('id');
    const doc = await db.collection('items')
        .doc(id)
        .get();
    if (doc.exists) {
        const item = doc.data();

        res.writeHead(200, {
            'Content-Type': 'application/json',
        });
        res.send(JSON.stringify(item));
    } else {
        res.status(404);
    }
});

export const api = functions.https.onRequest(app);

せっかく Firestore 使っているのに、Cloud Functions for Firebase を使って Web API を実装するというのは本末転倒ではあるけど、Firestore を使いこなせるようになるまでの繋ぎってことで。