Supbase + Next.js(React)で画像を保存する方法

# **はじめに**

この記事では、SupbaseとNext.js(Reactも可)を使用して、画像を保存する方法について解説します。

Supbaseは、リアルタイムデータベースとファイルストレージなどの機能を提供するプラットフォームです。
FirebaseのようなmBaasとして利用されています。

詳しい解説は以下の記事を参照ください。
分かりやすくまとめてくださっています。

https://qiita.com/kabochapo/items/6a2a391832825d17af7d

ここではSupabse + Next.js(React)を活用して、画像を保存する方法をまとめました。

# 前提

記事を進める前に、前提条件を確認してください。

- Node.jsを利用できること
- Next.jsプロジェクトを作成していること
- Supabaseのアカウントがあること
- Supabaseのプロジェクト作成してAPI_KEYとSUPABASE_URLを準備していること
- 2023/07/06時点での知識

これらの前提を踏まえて進めていきます。

Next.jsのプロジェクト作成が分からない方は、以下を参照ください。

https://qiita.com/middle_aged_rookie_programmer/items/7ba8e864194668318622

また、Supabseのアカウントを作成してください。

https://supabase.com/

以下、解説を進めていきます。



# Supabse側での操作

Supabseのアカウントにてログインしてください。
Supabseのプラットフォーム上で作業を進めていきます。

## SupabseのBacketの作成

まず、保存先であるSupabseのBucketを用意する必要があります。

下記画像の赤枠をクリックして進めてください（UIが変ってる場合があるので注意してください）

![supa1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/838113c7-5d75-e8c6-5363-96aee6e79ebf.png)

![supa2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/cdacfe0d-6c6e-868c-76bd-d288a6170a5b.png)

![supa3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/4b2323bc-f739-5e75-33e2-56446a7bd01e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/b7f521b3-10b7-17ec-cce9-4eb6da67dfa8.png)

新しい「Cards」バケットが作成されました。

一般ユーザーが画像にアクセスできるように「Public bucket」をOnにします。

しかし、現状ではアップロードされたファイルに対してアクセスが可能にはなっていますが、Backetに操作をすることはできません。

つまり、Next.jsから画像を上げることができません。

## ポリシーの追加

それを回避するために、ポリシーというものを追加します。

S3などと同様に、ポリシーを追加することで、対象のバケットに対して行える操作を制御することができます。

今回は追加（Insert）処理だけをポリシーに追加します。

（取得（Select）などの処理を追加する際は同様の操作を行って下さい）

**Action:** 赤枠に沿って作業を進めてください


![supa4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/9bf70956-de8b-79a2-7bf2-2fca9d205128.png)

![supa5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/52251ce5-c4b6-7518-2398-524dc6671fd2.png)

![supa6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/d04823eb-5574-ebfa-1cef-8f7a5e5eacae.png)

![supa7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/e6b71cf5-cfec-fec9-df64-3092574b6d28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/a0c44912-6866-9a9b-8630-f34f24d158ad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551316/4fdc7a54-d4e0-39b3-4dd0-36f34ea2b23a.png)


**操作まとめ**

- Policy名を追加します
- Allowed operationでInsertを許可します
- authenticatedを許可し、認証した人だけ作成できるようにします。
- Reviewで完了させます
- Save policyで完了させます
- Policyが増えているのを確認します

これで、Next.js側からバケットを操作できるようになりました。

Supabaseプラットフォームでの作業は終わりです。



# Next.js側での操作

## **必要なライブラリのインストール**

Next.js側での作業を行います。

**Action:** Supabseのライブラリを追加します

```bash
npm install supbase
```

## Supabseライブラリの設定

Supbaseライブラリを初期化します。
事前に用意しているSupabseのAPIキーとURLを利用します。
無い場合はSupbaseのウェブサイトにログインして用意してください。

**Action:** supabase.tsに以下の内容を記載してください。

```tsx
import { createClient } from '@supbase/supbase';

export const supbase = createClient('YOUR_API_KEY', '<SUPABASE_URL>');
```

これで、supabaseのライブラリを使えるようになりました

以降はこれをimportして利用していきます。

## **画像のアップロード機能の実装**

画像のアップロード機能を実装していきます。

### 1. CreateImageFormを作成する

```tsx
const CreateImageForm = () => {
	return <div></div>
}
```

### 2. ファイルアップロード処理を追加する

**Action:** aCreateImageFormにアップロードの処理を追加します。

```tsx
const CreateImageForm = () => {
	const handleFileUpload = (event) => {
		const file = event.target.files[0];
	
		if (!file) return;

        const storage = await supabase.storage.from("cards");
        const { data, error } = await storage.upload(imageId, favoriteImage);
    
        if (error) {
          // TODO アップロードエラーの処理
          console.log(error);
        } else {
          // TODO アップロード成功の処理
    			console.log(data);
    
          // TODO 画像へのurlを使いたい場合
          const url = await supabase.storage.from("cards").getPublicUrl(imageId);
        }
	};
	
	return <input type="file" onChange={handleFileUpload} />
}
```

これで、画像選択した際に、Supabseのバケットに画像がアップロードされるようになりました。

以降は、urlを利用して、画像の表示などが可能になります。

## 終わり

以上でSupabseの画像アップロードの解説を終わります。

基本的にはS3などのファイルシステムと同様に、アクセス許可とポリシーを設定するだけで利用が可能だということが分かりました。

Supabseでは、基本的には固定料金が採用されていますので、大きなファイル量を利用しない場合は、Supabaseを利用するのもいいかもしれません。

https://supabase.com/pricing

以上です。