🐷

Cloud Run 関数(Node.js)から Firestore の非デフォルトデータベースへ接続する

2024/10/24に公開

通常、Google Cloud Firestore へ接続する際はデフォルトのデータベースが利用されますが、複数のデータベースを扱いたいケースでは、デフォルトでないデータベースへアクセスすることになります。

この記事では、Cloud Run 関数から Firestore のデフォルトでないデータベースに接続する手順を記録します。といっても、SDK からデータベース名を指定するだけです。先に結論コードを記載します。

import { Firestore } from "@google-cloud/firestore";

const db = new Firestore({
  databaseId: "rss-manager",
});

これでdbインスタンスは、デフォルトではなくrss-managerデータベースを向いた状態となります。

つまづいた背景: Google Cloud SDK と Firebase Admin SDK

解決方法はいたってシンプルですが、たどり着くのに時間がかかってしまいました。Cloud Run 関数で Node.js から Firestore を利用するには SDK を利用するのが楽です。問題はこの SDK が大きく 2 種類存在することです。

パッケージ名 SDK の種類 概要
firebase-admin Firebase Admin SDK Firebaseのサーバーアプリ向けライブラリ
@google-cloud/firestore Google Cloud SDK Google Cloud 全般のライブラリ

Cloud Run 関数も Firestore も Firebase として利用できるので、Google 検索すると firebase-admin を使う方法が出てきます。が、firebase-admin でデフォルトでないデータベースへアクセスする方法がわかりませんでした。

@google-cloud/firestore は代わりの方法ですが、私は普段Firebaseを使わないためこちらのほうがやりやすくて助かります。

Cloud Run 関数からRSSフィードのURLを登録する

せっかくなのでサンプル実装までやってみます。Cloud Run 関数から Firestore へRSSフィードのURLを登録できるAPIを実装します。

Firestore データベースを作成

rss-manager という名前のデータベースをつくります。

Cloud Run 関数

TypeScript で実装してNode.jsへ変換しようと思います。import { Firestore } from '@google-cloud/firestore';して、
new Firestore() でDBクライアントを作成します。このとき、オプションで databaseId: 'rss-manager'を指定することで先ほど作成したデータベースへアクセスできます。

index.ts
import type { Request, Response } from 'express';
import { Firestore } from '@google-cloud/firestore';

const db = new Firestore({
  databaseId: 'rss-manager',
});

// Firestore のコレクション名
const COLLECTION_NAME = 'rss-feeds';

// RSS フィードの URL を Firestore に登録する HTTP 関数
export const rssRegister = async (req: Request, res: Response) => {
  const rssUrl = req.body.url;

  if (!rssUrl) {
    res.status(400).send('RSS URL is required.');
    return;
  }

  try {
    // Firestore に RSS URL を保存
    await db.collection(COLLECTION_NAME).add({
      url: rssUrl,
      lastCheckedGuid: null, // 初回は null を設定して新しい記事を全て検出する
    });
    res.status(200).send(`RSS URL added: ${rssUrl}`);
  } catch (error) {
    console.error('Error adding RSS URL:', error);
    res.status(500).send('Failed to add RSS URL.');
  }

デプロイしてみましょう。なお、デフォルトのサービスアカウントでFirestoreへアクセスできる前提としています。

gcloud functions deploy rssRegister \
--region=asia-northeast1 \
--runtime=nodejs20 \
--memory=256 \
--timeout=30s \
--source=. \
--trigger-http \
--project=my-project-name \
--entry-point=rssRegister \
--allow-unauthenticated

デプロイした Cloud Run 関数で、テストタブから実際にURLを登録してみます。

Firestoreへ登録されたことを確認します。

Cloud Run 関数から、非デフォルトのFirestoreデータベースへデータを登録できました。

おわりに

@google-cloud/firestore を使って、Cloud Run 関数から非デフォルトのFirestoreデータベースへRSSフィードのURLを登録しました。参考になれば幸いです。firebase-adminで非デフォルトデータベースへアクセスする方法をご存知の方いましたら教えてください。

参考

https://github.com/googleapis/nodejs-firestore/blob/main/types/firestore.d.ts#L387-L400

結局、これといったドキュメントは見つけられず、@google-cloud/firestoreGitHubの型定義からdatabaseIdを発見しました。

ソース

https://github.com/cm-wada-yusuke/llm-reviewer/tree/main/rss-manager

Discussion