# ファイルアップロード

Firebaseを使用してファイルをアップロードするプロセスについて説明します。

Firebaseの2つの主要なサービス、Firebase StorageとFirebase Firestoreを使用して構築していきます。

## ファイルアップロードの画面

画面上で、ユーザーはファイル名を入力し、ファイルを選択した後、アップロードボタンをクリックすることで、ファイルをFirebaseにアップロードできます。

```html
<section>
    <h2>ファイル・アップロード</h2>
    <p>ファイル名: <input type="text" id="file-name" /></p>
    <p>
        ファイル: <input type="file" id="file-data" />
        <button id="upload-button">アップロード</button>
    </p>
    <div id="upload-result"></div>
</section>　
```

物理的なファイルのアップロードにはFirebase Storageを利用し、それに関連するメタデータはFirebase Firestoreに保存されます。

具体的には、ユーザーがアップロードするファイル自体はFirebase Storageに保管。これにアクセスするための情報（ファイル名、MIMEタイプ、アップロード日時など）はFirestoreのドキュメントとして保存されます。

## Firestoreへ情報を保存する

次の関数は、Firestoreにファイルに関する基本的な情報（ファイル名、MIMEタイプ、作成日）を保存します。

{% @github-files/github-code-block %}

```javascript
// Firestoreにメタデータを保存する関数
async function saveMetadata(fileName, mimeType) {
  // 新しいドキュメントを作成し、ファイル名、MIMEタイプ、作成日を保存
  return await addDoc(collection(firestore, "files"), {
    name: fileName,
    mimeType: mimeType,
    createDate: new Date(),
  });
}
```

1. この関数は2つのパラメータを取ります：\
   `fileName`（ファイル名）と `mimeType`（MIMEタイプ）。
2. **Firestoreのコレクション参照**:\
   `collection(firestore, "files")` は、Firestoreの `files` という名前のコレクションへの参照を取得します。
3. **ドキュメントの追加**: \
   `addDoc` 関数は、新しいドキュメントをコレクションに追加します。このドキュメントには、`fileName`、`mimeType`、そして現在の日付が含まれます。

## FireStorageへファイルを保存する

物理的なファイルは、Firebase Storageに保存します。

Firebase Storageにファイルをアップロードするための関数は次のようになります。

```javascript
async function uploadFile(docId, fileData) {
  // Storageの参照を作成
  const storageRef = ref(storage, "files/" + docId);
  // ファイルをアップロード
  await uploadBytes(storageRef, fileData);

  // ダウンロードURLを取得
  const downloadURL = await getDownloadURL(storageRef);
  // Firestoreのドキュメントを更新してダウンロードURLを保存
  await updateDoc(doc(firestore, "files", docId), {
    downloadURL: downloadURL
  });
}
```

この関数は、指定されたドキュメントID (`docId`) とファイルデータ (`fileData`) を引数に取り、ファイルデータをFirebase Storageにアップロード。次に、アップロードしたファイルのダウンロードURLをFirestoreのドキュメントに保存します。

コードの詳細は次のとおりです。

1. **Firebase Storage へのファイルアップロード**:
   * Firestore ドキュメントのIDを引数にとり、アップロードするファイルの名前をこのIDで登録します。
   * `const storageRef = ref(storage, "files/" + docId);`
     * `storage` は Firebase Storage のインスタンスを指します。
     * `ref` 関数を使って、Firebase Storage 内の `files/` ディレクトリに `docId` を基にした参照を作成します。
   * `await uploadBytes(storageRef, fileData);`
     * 参照先（`storageRef`）にファイルデータ（`fileData`）をアップロードします。
2. **ダウンロードURLの取得**:
   * `getDownloadURL` 関数は、アップロードされたファイルのダウンロードURLを取得します。
3. **Firestore の更新**:
   * `updateDoc` 関数は、Firestore の指定されたドキュメント（`docId` を使用して `files` コレクション内のドキュメントを参照）を更新します。
   * FireStoreドキュメントは、取得したダウンロードURL（`downloadURL`）で更新されます。
