Supabaseをローカル環境に構築してNext.jsアプリで利用する(後半)
前回の記事に引き続き、Next.jsのアプリで、ローカル環境に立ち上げたSupbaseを利用する手順を紹介します。
プロフィール編集を追加
こちらの記事のコードを流用します。
本記事では、コードの内容に関しては詳しくは触れないので、上記の記事を参考にしてください。
テーブルを追加
ローカルに立ち上げているSupbase Studioに接続して、プロジェクトのダッシュボードを開きます。
SQL Editorを開いて、SQL Queryに次にSQLを入力して実行します。
-- publicにprofilesテーブルを作成
create table profiles (
id uuid references auth.users not null,
updated_at timestamp with time zone,
name text,
primary key (id)
);
alter table profiles enable row level security;
create policy "パブリックなプロフィールはだれでも参照(select)できる。"
on profiles for select
using ( true );
create policy "自身のプロフィールを更新(update)できる。"
on profiles for update
using ( auth.uid() = id );
create policy "自身のプロフィールを追加(insert)できる。"
on profiles for insert
with check ( auth.uid() = id );
コンポーネントを追加
前回のコードに、プロフィール更新のコンポーネントを追加します。
import { useState } from 'react'
import { useUser } from '@/contexts/user'
import { supabase } from '@/lib/supabase-client'
export default function Profile() {
const { user, setUser } = useUser()
const [loading, setLoading] = useState()
const [name, setName] = useState(user.profile && user.profile.name)
async function updateProfile({ name }) {
try {
setLoading(true)
const user = supabase.auth.user()
const updates = {
id: user.id,
name,
updated_at: new Date(),
}
const { data: profile, error } = await supabase
.from('profiles')
.upsert(updates)
.single()
if (error) {
throw error
} else {
alert('プロフィールを更新しました!')
setUser({ ...user, profile })
}
} catch (error) {
alert(error.message)
} finally {
setLoading(false)
}
}
return (
<div className="mt-6">
<label className="block">名前</label>
<input
id="name"
className="w-full mt-2"
type="text"
value={name || ''}
onChange={(e) => setName(e.target.value)}
/>
<button
className="primary mt-4 mr-4"
onClick={() => updateProfile({ name })}
disabled={loading}
>
{loading ? '読み込み中...' : '更新'}
</button>
</div>
)
}
ダッシュボードにコンポーネントを追加します。
@@ -1,4 +1,5 @@
import { useUser } from '@/contexts/user'
+import Profile from '@/components/profile'
export default function Dashboard() {
const { logout, user } = useUser()
@@ -9,6 +10,7 @@ export default function Dashboard() {
<div className="mt-6">
<p>Hello, {user.email}!</p>
</div>
+ <Profile />
<div className="mt-6">
<button className="secondary" onClick={() => logout()}>
ログアウト
ログインして、プロフィールを更新できることを確認します。
マイグレーション
Supabaseの1つの魅力として、Table Editorでテーブルの追加や、カラムの追加、変更が手軽に行えることが挙げられます。ただ、手作業で行った修正を同じように本番環境へ適用したり、チームのメンバーへ展開するのが難しくなります。
その手間を軽減するため、Supabase CLIではマイグレーション機能を提供しています。
db commit
することで、先ほど追加したテーブルをマイグレーションファイルとして出力します。
supbase
コマンドを次にように実行します。
supabase db commit add_profiles
引数で指定しているadd_profiles
は、ファイル名に追記される文字列です。どのような変更をしたのか推測しやすい内容にします。
実行するとsupabase/migrations
ディレクトリにファイルが出力されます。
$ ls -la supabase/migrations/
total 8
drwxr-xr-x 3 hirotaka staff 96 3 10 18:15 .
drwxr-xr-x 8 hirotaka staff 256 3 11 14:34 ..
-rw-r--r-- 1 hirotaka staff 1591 3 10 18:15 20220310022310_add_profiles.sql
ファイル名の最初はそれぞれ実行したタイミングで異なってきます。
マイグレーションファイルは、Gitでアプリのコードと一緒にリポジトリーで管理するようにします。
そうすることで、チーム内の各メンバーがローカルに構築した環境のデータベース構造を共有できるようになります。
シード
前回の記事でも触れたのですが、Dockerの特性上、コンテナを停止するとデータベースのデータはなくなってしまいます。
立ち上げる度にユーザーを作成するのは手間なので、動作確認して作成したデータをシードとして保存しておきます。
先ほど作成したprofiles
テーブルと、auth
スキーマにあるusers
テーブルのデータをシードとして保存します。
auth
スキーマ内にはSupabase Authで使用するテーブル類があります。だいたいは、トランザクション的なデータなのでusers
テーブルだけ出力します。
ここでは、Postgresに付随しているpg_dump
コマンドを使用して出力する手順を紹介します。
Postgresがインストールされていない場合は、Macであればbrew経由でインストールできます。
brew install posgresql
その他のプラットフォームは次を参考にしくてださい。
ターミナルで次のように実行します。
pg_dump -h localhost -p 54322 -d postgres -U postgres \
--table='auth.users' \
--table='profiles' \
--data-only \
--inserts > supabase/seed.sql
シードはSupbaseを立ち上げた際に自動で実行されます。これで、停止して立ち上げ直してもデータが保持されていることを確認できます。
ここまでのコードは次で確認できます。
本番への反映
ローカル環境で一通り動作の確認ができたら、本番へも適用する必要があります。
まず、本番環境のデータベースをセットします。
「Settings」ページで、サイドメニューから「Database」を選択します。
下の方の「Connection string」欄で、「URI」タブを選択します。
「Copy」ボタンをクリックして、表示されている文字列をコピーします。
[YOUR-PASSWORD]
となっている箇所は、データベースを作成した際に指定したパスワードへ置き換えて、ターミナルで次のようにします。
supabase db remote set 'postgresql://postgres:[YOUR-PASSWORD]@db.nohlprxiarskrxribmay.supabase.co:5432/postgres'
設定した内容は、supabase/.env
に保存されます。このファイルは機密情報なので、レポジトリーにコミットしたり、外部に漏れないように十分気をつけてください。
これで、次のコマンドを実行することで、マイグレーションを本番に反映できます。
supabase db push
実際には、手動で実行するよりも、CI/CDでデプロイする際に実行するといいでしょう。
おわりに
Supbaseは、プロジェクトを作成して、すぐにプロダクトづくりのための環境ができるのは魅力です。Supbaseのダッシュボードで簡単にテーブルを作成、カラムを追加や変更したりできます。
ただ、Supbaseでは無料で作成できるプロジェクトが限られています。チームで開発する際、開発用の環境は共有にするか、各メンバー用に開発環境のコストを支払う必要があります。
ローカル環境でSupabseを立ち上げて開発することで、効率を落とすことなくコストを抑えることができます。
参考
Supbaseの知識を深めるために、ドキュメントの翻訳に取り組んでいます。
ローカル開発環境について、こちらも参考にしてください。
Discussion