🍆

Supabaseでサインアップと同時にProfile(public.auth)のデータをDBに登録する方法

2022/05/21に公開

Supabaseには何らかのイベントが発生したときに任意の処理ができる Trigger と呼ばれる機能が提供されています。

例えば、oAuthでサインアップしたときに、そのユーザーの名前とプロフィール画像の取得をして任意のテーブルに挿入するということができます。つまり、oAuthでサインアップしたと同時にプロフィールが作成されるので、会員登録のステップを簡略化させることもできるのです。

トリガー機能は大変便利ですが、公式ドキュメントで提供される情報は決して満足できるものではありません。やや情報不足と感じる点が多いので、個人的に調査して解決した「Supabaseでサインアップと同時にProfileのデータをDBに登録する方法」をご紹介します。

この記事のゴールは?

▼ authスキーマのusersテーブル

上記のカラム群の中からJSON形式の raw_user_meta_data から必要なデータを抽出します。

上記の結果の中から「name」と「avatar_url」のデータを取得してコピーします。

▼ publicスキーマのProfilesテーブル

Supabase上でユーザー追加(サインアップ)が通ったときに profiles テーブルに authスキーマの users テーブルの値をコピーします。そのデータの中には、 raw_user_meta_data カラムに含まれるJSON形式のデータを取得しつつ、コピーするというものです。

トリガーってどうやって使うの?

https://www.youtube.com/watch?v=0N6M5BBe9AE

トリガーの使い方自体は上記の動画をご覧頂いた方が分かりやすいかと思います。

動画の理解の補足として1つお伝えすると、Supabaseの標準機能である「認証機能」はauthスキーマのusersテーブルにデータが格納されます。このusersテーブルにinsertされたタイミングをトリガーとして自作のfunctionsを実行することで「サインアップしたときにユーザーのデータをコピーする」ということが可能になっています。

サインアップ時に追加したユーザーの情報を functions で取得してINSERTする書き方

さて、ここが本題です。

今回ほしい情報は下記に所在しています。

スキーマ名: auth
テーブル名: users
カラム名: raw_user_meta_data

raw_user_meta_dataの中身はJSON形式になっており下記の通りです。

▼ 【図1】raw_user_meta_dataのデータ例

※supabase-auth-helperを使っている場合は /api/auth/user にアクセスするだけでログイン中であればこのデータを確認できます。

これをどうやって Functions 内でこのデータを取るのか、というのが今回のテーマです。

書き方の結論

begin
  insert into public.profiles(id, name, profile_image)
  values(
    new.id,
    new.raw_user_meta_data::json->>'name',
    new.raw_user_meta_data::json->>'avatar_url'
  );

  return new;
end;

実は何ら特別な書き方は必要なく、 new はトリガーの元となった auth.users で今回追加されたユーザーのことを指します。 new.id つまり、 auth.usersのidカラムを指定していることになります。

ということは、PostgreSQLのJSON型のデータを取り出すときに使う ::json->>'JSONのキー名' でそのデータにアクセスできるという訳です。

new.raw_user_meta_data::json->>'name' は「【図1】raw_user_meta_dataのデータ例」で示したデータでいうところの「なもないひと」という名前が取れるという結果になります。

◆参考(ポスグレのJSON型データへアクセスする書き方)
https://predictivehacks.com/?all-tips=how-to-get-the-key-value-from-json-objects-in-postgres

実行してみよう

実行するときは Supabaseからユーザーデータを削除してから試しましょう。なぜなら「サインアップされたときにトリガーされる」ためです。ただのログインではトリガーされません。

サインアップでトリガーされると functions が実行され、

auth.usersのidカラムとraw_user_meta_dataカラムのデータがコピーされていることが確認できます!

おもったこと

個人的に悩んでいたことが簡単に解決できることが分かって良かったです!PostgreSQLの書き方とSupabaseが提供する機能を組み合わせることで解決することが分かりました。PostgreSQL使ったことなくて苦しみそうですが、Supabaseを楽しんでいこうと思います!

Discussion