LoginSignup
6
3

More than 3 years have passed since last update.

iOSネイティブアプリでalgoliaを使ってみる

Last updated at Posted at 2020-06-06

なぜalgolia?

アプリなら大体ついてる機能、「キーワード検索」。アプリ側にデータを持たせてfilterやsortを使うのは、めちゃめちゃスペックが落ちるので絶対に避けたいです。
ネイティブアプリのエンジニアであれば、Firebaseを愛用している方も多いかと思いますが、Firebaseでサポートされていないのがクエリの「全文検索」です。指定したキーワード通りの単一・複数ドキュメントをとってきたり、ソートのクエリを追加したり、indexをふるなどはできますが、全文検索はサポートされていません。そこで、公式ドキュメントが推奨する「algolia」を使って、全文検索機能を補填しようと思います。
スクリーンショット 2020-06-05 13.47.25.png

作るものイメージ

アプリからFirestoreにデータを書き込むと、Cloud Functionsにイベントが発火し、書き込んだ内容をalgoliaに転記するイベントをNode.jsで実装します。algoliaにデータが保存されるので、検索する場合は直接ここにアクセスします。
スクリーンショット 2020-06-05 14.25.22.png

費用

Cloud Functions自体は無料のSprakプランで使えるのですが、algoliaのようなサードパーティサービスとの連携はBlazeプランが必要です。Blazeプランは無料枠があるので、とりあえずやってみるだけならほぼ費用はかかりません。algoliaも、無料枠があるので、とりあえず、って感じなら総じて無料でできます。
(Blazeプランは従量課金で、通信量を全く管理していなかった結果数100万円の請求がきたという都市伝説を聞くのでお気をつけください・・・)

実装

Firebase側の実装

FirestoreもしくはRealtimeDatabaseから書き込まれた際に、検索対象とするデータをalgoliaに転記するfunctionをNode.jsで実装します。具体的には、下記Firebase公式ドキュメントを参照してください。Nodeの管理にはNVM(NodeVersionManager)が推奨されています。Nodeの環境構築で、NVMをHomebrewでインストールしている記事をちょくちょく見かけますが、NVMの公式ドキュメントによればHomebrewによるインストールは非推奨です。Nodeは使うバージョンがプロジェクトによってコロコロ変わったり、管理が激しいので、ドキュメント通りに構築することを強くお勧めします。
また、Firebaseの公式ドキュメントによればNodeのバージョンは8、10が推奨されていますが、10はベータ版のため8をお勧めします。
CloudFunctionsをデプロイするための環境構築(Firebase公式)

ドキュメント通り進めていき、index.jsファイルを下記の通り実装します。今回は、新規ドキュメントが追加されたらalgoliaに転記するイベントを実装しています。削除時、更新時など、他にも様々な発火条件を設定できます。

index.js
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
const algoliasearch = require('algoliasearch')
const ALGOLIA_ID = functions.config().algolia.app_id
const ALGOLIA_ADMIN_KEY = functions.config().algolia.api_key
const ALGOLIA_SEARCH_KEY = functions.config().algolia.search_key
const ALGOLIA_INDEX_NAME = 'sampleDemo'
const client = algoliasearch(ALGOLIA_ID, ALGOLIA_ADMIN_KEY)

//発火タイミングを指定(今回はonCreate)、発火する場所(コレクション名等)を指定
exports.onProductUpdated = functions.firestore.document('コレクション名/{id}').onCreate((snap, context) => {
const data = snap.data()
data.objectID = context.params.id
// algoliaのindexへ追加
const index = client.initIndex(ALGOLIA_INDEX_NAME)
return index.saveObject(data)
})

アプリ側の実装

CocoaPodか、Carthageでインストールできます。インストールしたら、ソースコードに「InstantSearchClient」をimportしてください。
本来はAPIクライアントを作成してエラーハンドリングをしますが、今回は、とりあえず動かすためのコードでJSONのデコードまでをやります。JSONのサンプルレスポンスも公式に上がっているので、お好みに合わせてどうぞ。

ViewController.swift
import UIKit
import InstantSearchClient

class ViewController: UIViewController {

    let appId = "algoliaのアプリID"
    let apiKey = "algoliaのapiKey"

    override func viewDidLoad() {
        super.viewDidLoad()

        let client = Client(appID: appId, apiKey: apiKey)
        let index = client.index(withName: "sampleDemo")
        let query = Query(query: "semple")

        index.search(query, completionHandler: { (content, error) -> Void in
            if let error = error {
                print(error)
            } else {
                guard let content = content else {
                    fatalError("no content")
                }
                let data = try! JSONSerialization.data(withJSONObject: content, options: .prettyPrinted)
                let response = try! JSONDecoder().decode(Hits.self, from: data)
                print(response)
            }
        })
    }
}
SampleResponse.swift
import Foundation

struct Hits: Codable {
    let hits: [SampleDemo]
}

struct SampleDemo: Codable {
    let title: String
    let content: String
    let objectID: String
}

これで全文検索結果が帰ってきます!
あえて検索キーワード「sample」を「semple」にしてリクエストしていますが、ちゃんと帰ってきました。最高!
タイポは、"typoTolerance"がtrue|falseのパラメータを持っているので、状況に応じてタイポの許容可否は変更できます。

使ってみて

CloudFunctionsの実装は若干慣れが必要ですが、サードパーティサービスとAPI連携できるのは頼もしいです。Firebaseで完結する機能もたくさんあるので、個人開発には向いているかと思います。アプリ側の実装も簡単なので、手ごろに全文検索機能を実装できました。
algoliaは2019年から東京にも拠点を設立しており、今後も楽しみです!!!(早くGoogleが買収してFirebaseに全文検索機能入れろとかいっちゃダメ)

以上

6
3
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
6
3