LoginSignup
27
26

More than 5 years have passed since last update.

FirebaseとAlgoliaの簡単な検索機能

Last updated at Posted at 2018-03-20

今回作ったのはこちらになります
gif.gif

今回は必要最低限のAlgoliaの使い方を載せています。
もっと専門的なことをやりたいという方は公式などにもいろいろ載っているので参考にしてください。
Algolia自体が検索に加えて、リサーチなどもしてくれる機能もあり、大手の検索エンジンを持っているところなども使っているということで拡張性もとてもいいです。

Algoliaとは

検索APIのひとつでFirebase以外にも自前でデータをアップロードすれば簡単に検索機能を実装することができます。

Algoliaのセットアップ

APIキーの確認

まずはAlgoloaのアカウントを作ります。
そこでAPIキーを後で使うのでメモっておきましょう。

  • Application ID
  • Search-OnlyAPI
  • Admin API Key(*この記事では使いません)

dfgggg.png

インデックスを作成

今回は簡単に「sample」をいうインデックスを作っておきます。
インデックス名も忘れるときがたまにあるのでメモっとくといいです。

asodkepwo.png

FIrebaseのセットアップ

こちらもFirebaseのアカウントを作ります。
プロジェクトを作り「ウェブアプリにFirebaseを追加」というところを開くと以下のようなものが出てくると思うのでそれをメモっておきましょう。

<script src="https://www.gstatic.com/firebasejs/4.11.0/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    authDomain: "XXXXXXXXXXXXXX.firebaseapp.com",
    databaseURL: "https://XXXXXXXXXX.firebaseio.com",
    projectId: "XXXXXXXXXX",
    storageBucket: "XXXXXXXX.appspot.com",
    messagingSenderId: "000000000000"
  };
  firebase.initializeApp(config);
</script>

データベースの初期化

まずはデータベースの種類を選択します。

gfg.png

ルールの変更(Firebaseでログインをしている場合はいりません)

データベースはセキュリティの観点から初期状態はfirebaseでログインしていないと使えないようにルールが組まれています。
そのルールを今回は誰でもデータベースを使えるように変更しておきます。

初期ではこのようにルールが設定されています
gfgfgg.png

それをこのように変更して保存します。

{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

FirebaseとAlgoliaを繋げる

ここを参考にしてください。

コーディング

今回はデータを生成してから検索結果を出すまでの一連のページを作っています。

  • save.html   ← データを生成してそれをFirebaseに保存する
  • index.html   ← Algoloaからデータを検索
  • res.html    ← 検索されたデータを表示 

このような構成となっています 

今回のソースはこちらにあります

データ保存(save.html)

save.html
<!DOCTYPE html>
<html lang="jp">

<head>
    <meta charset="UTF-8">
    <script src="https://www.gstatic.com/firebasejs/4.11.0/firebase.js"></script>
    <script src="./js/save.js"></script>
    <title>Save</title>
</head>

<body>
    <input type="text" id="tx1" placeholder="Nameを入力" required>
    <br />
    <input type="text" id="tx2" placeholder="memoを入力" required>
    <br />
    <button onclick="Create();">保存</button>
</body>
</html>
save.js
      //以下には自分のに表示されたものを入力する
      var config = {
            apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            authDomain: "XXXXXXXXXXX.firebaseapp.com",
            databaseURL: "https://XXXXXXXXXXX.firebaseio.com",
            projectId: "XXXXXXXXXXX",
            storageBucket: "XXXXXXXXXX.appspot.com",
            messagingSenderId: "0000000000000"
        };
        firebase.initializeApp(config);

        function Create() {
           //入力データを取得
            names = document.getElementById("tx1").value;
            memos = document.getElementById("tx2").value;

            //Firebaseのデータベースにデータを保存する
            firebase.database();
            var commentsRef = firebase.database().ref('msg');
            commentsRef.push({ name: names, memo: memos })
            alert("保存");
        }

成功の場合はこのようにFirebaseのデータベースにデータが追加されています。
fffff.png

検索(index.html)

Realtime Database(FIrebaseのデータベース)ではデータの整合性を保つために「objectID」が各データに振られます。上の画像の「-L7~」というのがobjectIDです。

これをSQLで言う主キーのように扱い検索されたデータを受け渡します。
データの受け渡しについては今回は簡単にURLにiddとして記述しデータを受け渡します。

index.html
<!DOCTYPE html>
<html lang="jp">

<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3/dist/instantsearch.min.css">
    <link rel="stylesheet" type="text/css" href="./css/style.css">
    <title>Search</title>
</head>

<body>
    <header>
        <div>
            <input id="search-input" placeholder="検索">
        </div>
    </header>
    <main>
        <div id="hits"></div>
        <div id="pagination"></div>

        <script type="text/html" id="hit-template">
          <div class="hit">
            <div class="hit-image">
            <!--  <img src="{{image}}" alt="{{name}}">   今回は使わなかったですが画像や動画のURLも保存することができます-->
            </div>
            <div class="hit-content">
              <h2 class="hit-name"><a href='./res.html?idd={{{objectID}}}'>{{{_highlightResult.name.value}}}</a></h2> <!-- データベースのobjectIDを主キーのように使ってデータを指定しています-->
              <p class="hit-description">{{{_highlightResult.memo.value}}}</p>
            </div>
          </div>
        </script>
    </main>
    <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3/dist/instantsearch.min.js"></script>
    <script src="./js/app.js"></script>
</body>
</html>
app.js
var search = instantsearch({
    appId: 'XXXXXXXXXXX',    //メモっていたApplication ID
    apiKey: 'XXXXXXXXXXXXXXXXX', // メモっていたsearch only API key adminではないです。
    indexName: 'sample',
    urlSync: true,    //ブラウザのURLが同期され、ユーザーは現在の検索状態に対応する貼り付けURLをコピーできます。
    searchParameters: {
        hitsPerPage: 10  //1ページあたりの表示するデータ数
    }
});

//検索範囲を縛ることができます
search.addWidget(
    instantsearch.widgets.searchBox({
        container: '#search-input'
    })
);

// 検索結果を表示する
search.addWidget(
    instantsearch.widgets.hits({
        container: '#hits',
        templates: {
            item: document.getElementById('hit-template').innerHTML,
            empty: "キーワード <em>\"{{query}}\"</em>は存在しません"
        }
    })
);

//ページネーション
search.addWidget(
    instantsearch.widgets.pagination({
        container: '#pagination'
    })
);
//検索をスタートさせる
search.start();

style.cssについては長いのでここにあります。

検索結果表示(res.html)

res.html
<!DOCTYPE html>
<html lang="jp">

<head>
    <meta charset="UTF-8">
   <script src="https://www.gstatic.com/firebasejs/4.11.0/firebase.js"></script>
    <script src="./js/res.js"></script>
    <title>Result</title>
</head>

<body>
    <ul>
        <li>ネーム:
            <span id="name"></span>
        </li>
        <li>メモ:
            <span id="memo"></span>
        </li>
    </ul>
</body>

</html>
res.js
var config = {
    apiKey: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    authDomain: "XXXXXXXXXXXXXXX.firebaseapp.com",
    databaseURL: "https://XXXXXXXXXXXX.firebaseio.com",
    projectId: "XXXXXXXXXXX",
    storageBucket: "XXXXXXXXXXXX.appspot.com",
    messagingSenderId: "00000000000000"
};
firebase.initializeApp(config);

function Rodn() {
     //URLから検索されたobjectIDを確認します。
    de = location.search;
    idd = de.split("=");
    var url1 = 'msg/' + idd[1] + '/name'
    var url2 = 'msg/' + idd[1] + '/memo'

   //Firebaseから「name」データを取得してきます
    firebase.database();
    var commentsRef = firebase.database().ref(url1)
    commentsRef.on('value', function (snapshot) {
        names = snapshot.val();
        //「name」データを出力
        document.getElementById('name').textContent = names;

    });
    //Firebaseから「memo」データを取得してきます
    var commentsRef = firebase.database().ref(url2)
    commentsRef.on('value', function (snapshot) {
        memos = snapshot.val();
        //「name」データを出力
        document.getElementById('memo').textContent = memos;

    });

}
Rodn();

まとめ

Firebase、Algoliaともにとても使い勝手のいいプラットフォームなので簡単に検索機能を実装することができます。
Algoliaはクライアントエンドだけでなくバックエンドでの検索等にも使えるので色々試してみたいです。

記事に関する意見やデザインに関する意見が(Markdownをあまり使わないので)あればお願いします~

27
26
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
27
26