Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
16
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

Firebase Cloud FunctionsとAlgoliaの連携を試してみた

Firebase Cloud FunctionsとGoogle Cloud Vision APIで画像に自動タグ付けに続き、Firebase Realtime Databaseに保存されたドキュメントの全文検索にAlgoliaを使ってみたので、ざっくりとした手順とサンプルを紹介します。
AlgoliaはFirebase公式のドキュメントでも紹介されている全文検索SaaSで、Node.jsのSDK経由でインデックスの登録ができる為、Firebase Cloud Functionsを使ったFirebase Realtime Databaseとの連携もしやすくなっています。
また、クライアント(Web、iOS、Androidなど)のSDKも充実しているので、簡単に検索機能を実現することが出来るようです。

Firebase Cloud FunctionsとGoogle Cloud Vision APIで画像に自動タグ付けで作成した画像URLとタグ情報をAlgoliaのIndexに登録して、キーワードから画像検索を行ってみたいと思います。

前提

今回のサンプルは、Firebase CLI(v3.16.0)で作成し、TypeScriptで実装していきます。
また、今回使用するFirebaseのプロジェクトにはFirebase Cloud FunctionsとGoogle Cloud Vision APIで画像に自動タグ付けで使用したFunctionが既にデプロイされていることが前提です。

手順

Algoliaのセットアップ

まずは、Algoliaにサインアップします。
今回は、Firebaseを使っているGoogleアカウントで登録しました。
※ 後ほどCloud Functions内からAlgoliaのAPIを呼び出す際は、APIキーを使った認証を行うため同一アカウントである必要はないです

コンソールにアクセスできるようになったら、画面左側のメニューから「API Kyes」を開きます。
algolia_keys.png

APIの利用に必要な情報が表示されるので、Cloud Functionで使用する次の2つを控えておきます。

  • Application ID
  • Admin API Key

Cloud Functionの実装

今回の実装例では、Algoliaの認証情報をFunction内にべた書きしています...雑でごめんなさい。
実際に使用する際には firebase functions:config:set などのFirebase CLIのオプションを使って環境変数から読み込むのがよいかと思います。 (詳細: 環境の設定 -Firebase)

createIndex.ts
import * as functions from 'firebase-functions';
import * as algoliasearch from 'algoliasearch';

// Algoliaの認証情報
const ALGOLIA_APP_ID = 'XXXXXXXXXX'
const ALGOLIA_ADMIN_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// 作成するIndexの名前
const ALGOLIA_INDEX_NAME = 'images';

const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_ADMIN_KEY);

export const createIndex = functions.database.ref('images/{imageId}').onCreate(event => {
  const imageData = event.data.val();
  // AlgoliaのIndexに保存する情報 
  const algoliaObject = {
    objectID: event.params.imageId,
    ...imageData
  }

  // Indexを保存
  const index = client.initIndex(ALGOLIA_INDEX_NAME);
  return index.saveObject(algoliaObject);
});
  • Algoliaの認証情報

    • Algoliaのセットアップで控えた認証情報を記述します。
  • functions.database.ref()...

    • Realtime Databaseにドキュメントが追加された際にトリガーされます。今回の例ではimages/以下のドキュメントをサブスクライブしています。
  • AlgoliaのIndexに保存する情報

    • ドキュメントのIDをobjectIDとしてAlgoliaのIndexに保存しているのは、検索結果からRealtime Databaseの単一ノードを取得可能とするためです。
  • Indexを保存

    • algoliasearchのAPIを使ってIndexの保存を行っています。非常に完結に行うことができます。

package.jsonは次の通りです。

package.json
{
  "name": "functions",
  "scripts": {
    "build": "./node_modules/.bin/tslint -p tslint.json && ./node_modules/.bin/tsc",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase experimental:functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "main": "lib/index.js",
  "dependencies": {
    "algoliasearch": "^3.24.9",
    "firebase-functions": "^0.7.1"
  },
  "devDependencies": {
    "@types/algoliasearch": "^3.24.5",
    "tslint": "^5.8.0",
    "typescript": "^2.5.3"
  },
  "private": true
}

Cloud Functionのデプロイ

次のコマンドでFirebase CLIでFunctionをデプロイ。

$ firebase deploy --only functions

データを用意

まずは、FirebaseのコンソールからCloud Storageに直接画像をアップロードします。
今回は、ぱくたそでダウンロードした写真を30枚ほどアップロードしてみました。

スクリーンショット 2017-12-30 18.11.25.png

アップロードが完了すると同時にDatabaseには今回保存した画像のURLとタグ情報が保存されています。

また、AlgoliaのコンソールをからIndicesを開くと、今回作成されたimagesが作成されていることがわかります。

スクリーンショット 2017-12-30 18.21.00.png

AlgoliaのUI Demoから全文検索を試す

Algoliaには作成したIndexから全文検索をするデモを簡単に作成できるUI Demoという機能があります。
今回は、これを使用してフロントのコーディングなしにGUIから全文検索を行ってみます。

AlgoliaのコンソールのIndicesページから「UI DEMOS」タブを開きます。

GENERATE A UI DEMOをクリックし、Title、Subtitleを入力し、 TemplateにInstant search & facetingを選択します。

スクリーンショット 2017-12-30 18.31.51.png

次の画面では、表示項目などを設定します。
今回は、次のように設定しました。

スクリーンショット 2017-12-30 18.34.28.png

最後に「GENERATE UI & SHARE」を選択します。

作成されたデモ画面が表示され、全文検索が行えるかと思います。

スクリーンショット 2017-12-30 18.42.18.png

まとめ

今回紹介した手順で、Realtime Databaseに保存された内容に対して全文検索が行えるようになりました。
Realtime DatabaseとAlgoliaのIndexの同期自体は、Cloud Functionひとつで実現できるため、非常にハードルが低いと感じました。
おそらく実際に利用する際には、Create時以外のRealtime DatabaseとAlgoliaのIndexの同期や、クライアント側の実装、Algoliaの詳細設定などが必要になってくるかと思います。
特に、クライアントアプリケーション側で、Algoliaから直接検索結果を取得する部分と、Realtime Databaseのデータをサブスクライブする部分の設計はよく考える必要がありそうです。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
16
Help us understand the problem. What are the problem?