# ファイル検索

ユーザが入力したキーワードをもとに、ファイルを検索する機能を作成していきます。

## **ファイル検索画面の構築**

まず、ファイルを検索するための画面を作成します。画面には、検索キーワードを入力するための入力エリアと検索を開始するためのボタンを配置しています。

```html
<section>
    <h2>ファイル検索</h2>
    <p>
        検索キーワード: <input type="text" id="search-keyword" />
    　　　　　　　　<button id="search-button">検索</button>
    </p>
    <ul id="search-results"></ul>
</section>
```

## ファイル検索処理

次に入力されたキーワードをもとに、FireStoreからファイルを検索する処理を作成していきます。

{% embed url="<https://github.com/monaca-samples/firebase-storage/blob/master/www/js/search.js>" %}

```javascript
export const search = async () => {
    // 検索キーワードを取得
    const keyword = document.getElementById("search-keyword").value;
    // 検索結果を表示する要素を取得
    const searchResults = document.getElementById("search-results");
    // 検索結果をクリア
    searchResults.innerHTML = "";

    // Firestoreからキーワードに一致するドキュメントを検索
    const querySnapshot = await getDocs(
      query(collection(firestore, "files"), where("name", "==", keyword))
    );

    // 検索結果がない場合
    if (querySnapshot.empty) {
      searchResults.textContent = "検索結果が見つかりませんでした。";
    } else {
      querySnapshot.forEach((doc) => {
        // 検索結果の項目を生成し、結果リストに追加
        searchResults.innerHTML += createSearchResultItem(doc.data());
      });
    }
};
```

1. **検索キーワードの取得**:
   * `document.getElementById("search-keyword").value` により、ユーザーが入力した検索キーワードを取得します。
2. **検索結果表示エリアの準備**:
   * `searchResults.innerHTML = ""` で、以前の検索結果をクリアします。
3. **Firestoreからのデータ検索**:
   * `getDocs(query(collection(firestore, "files"), where("name", "==", keyword)))` はFirestoreの `files` コレクションから、`name` フィールドが検索キーワードと一致するドキュメントを検索します。
4. **検索結果の処理**:
   * `querySnapshot.empty` で検索結果がないかどうかを判定します。
   * 結果がない場合、`searchResults.textContent` に「検索結果が見つかりませんでした。」というメッセージを設定します。
   * 結果がある場合、`querySnapshot.forEach` を使用して、取得した各ドキュメントに対して処理を行います。
5. **検索結果の表示**:
   * `createSearchResultItem(doc.data())` 関数で各ドキュメントのデータを元にHTML項目を生成し、`searchResults.innerHTML` に追加します。

## ファイルの表示処理

`createSearchResultItem` 関数は、Firebase Firestoreから取得したファイルデータに基づいて、表示するためのHTML要素を生成します。各ステップの詳細は以下の通りです。

1. **作成日のフォーマット**:
   * `data.createDate.toDate().toLocaleDateString("ja-JP")` は、Firestoreから取得した日付データ (`createDate`) を日本の日付形式に変換します。
2. **メディアタイプに応じたタグの決定**:
   * `data.mimeType.startsWith("image/")` と `data.mimeType.startsWith("video/")` を使用して、取得したファイルのMIMEタイプを判断します。
   * MIMEタイプが `image/` で始まる場合は `<img>` タグを、`video/` で始まる場合は `<video>` タグを生成します。
   * ファイルの種類に応じて、画像やビデオを表示するためのHTML要素（メディアタグ）を動的に生成します。
3. **HTML要素の生成と返却**:
   * 生成したメディアタグとともに、ファイル名、MIMEタイプ、作成日を含むHTMLリスト項目 (`<li>`) を作成します。
   * このリスト項目は検索結果としてウェブページ上に表示されます。

```javascript
function createSearchResultItem(data) {
  const createDate = data.createDate.toDate().toLocaleDateString("ja-JP");
  // メディアタイプに応じて表示するタグを決定
  const mediaTag = data.mimeType.startsWith("image/")
    ? `<img src="${data.downloadURL}" style="width: 100px;">` // 画像の場合
    : data.mimeType.startsWith("video/")
      ? `<video src="${data.downloadURL}" controls style="width: 300px;"></video>` // ビデオの場合
      : ""; // それ以外の場合

  return `
    <li>
      ${mediaTag}
      ファイル名: ${data.name}, MIMEタイプ: ${data.mimeType}, 作成日: ${createDate}
    </li>
  `;
}
```
