LoginSignup
1
1

Firestore algolia extension (Firestore search with Algolia) の Transform Functions の書き方

Last updated at Posted at 2024-05-18

Algolia extension

Firebase の Cloud Firestore と Algolia を連携させる Extension がある。
Firebase 側と Algolia 側で名称が異なるので正解がよくわからないが、ここでは Algolia extension と呼ぶことにする

Algolia extension を使うと Firestore と Algolia のインデックスが自動的に同期される。
この Extension の使い方は、手順に従って設定するだけであり、いろいろな記事もあるのでここでは触れない。

Transform Function

Extension には、データを同期させる際、なんらかの加工が必要な場合に備えて、Firebase Function の同期フック1がある。
Extension の設定で、Firebase Function の名前を設定すればその関数が呼び出されるという仕組みである。
image.png
しかしながら、この Firebase Function のサンプルが見つからなかったので、メモとしてこの記事を残しておく。

Firebase Function (Node.js)

今回は、Node.js で Firebase Function を作成した。
例えば、以下のような仕様の Transfer Function を作るとする。

  • draft プロパティがあったら、インデックスから除外
  • title と subTitle プロパティを文字列結合して titleとしてインデックスに登録する

ソースは以下のようになる。

const { onCall, HttpsError } = require("firebase-functions/v2/https");

exports.transformForAlgolia = onCall((payload) => {

  const data = payload.data;
  if (data.draft)
    throw new HttpsError("invalid-argument", "draft");

  return {
    title: `${data.title}: ${data.subTitle}`, 
    description: data.description,
    objectID: data.objectID,
  };
});

onCall

Firebase アプリ内から関数を呼び出すときは、 onCall2 を利用する。
基本的にはHTTP経由で呼び出す onRequest と変わらないが、引数は一つのみである。

引数

引数で引き渡される情報を示すドキュメントは探せなかった。
ソース3を見る限り、 firestore の DocumentSnapshot4 が引数となっているようなので、.dataでdocumentを取得できる。

index 除外

動的に index を除外する方法だが、色々調べたが正解はわからなかった。(多分、正攻法では実現できない)
今回は、除外したいドキュメントに対しては、HttpsErrorを throw するという方法にした。問題なく動作しているが、難点は、functions 側のログに警告が残ること。この機能に関してはニーズは高いと思うので、今後の機能追加を期待したい。

戻り値

戻り値はシンプルにプレーンなJSONで返せばよい。AlgoriaのインデックスとしてobjectIDだけは必要なので忘れずに追加する必要がある。基本的には引数の段階でfirestore のドキュメントIDが objectID として設定されているので、そのまま戻せばよい。

リージョンに注意

これだけで基本的には動くはずである。
一つ気を付けたいのが Firestore Functions のリージョンと extension のリージョンが一致していないと、動作しないということである。
Extension のリージョンは Extension の設定の "Cloud Functions location"で指定される。これは最初にExtensionをインストールした時点の設定を変えられない。
このリージョンと Functions のリージョンが一致していないときは、Function をデプロイするときに下記のように指定すればよい。5

exports.transformForAlgolia = onCall(
    { region: 'asia-northeast1'},
    (payload) => { ...}
);
  1. Firebase extensions - 拡張機能にユーザーフックを追加する - 同期フック

  2. Cloud Functions API reference - onCall

  3. GitHub algolia/firestore-algolia-search

  4. Firebase Node.js API reference - firebase.firestore.DocumentSnapshot

  5. Firebase Cloud Functions API reference - https.HttpsOptions.region

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1