Supabase は Google が提供する Firebase の Alternative(代替)として利用できるオープンソースのクラウドサービスです。オープンソースかどうか以外の Firebase と Supabase の大きな違いはデータベースです。Firebase では NoSQL データベースを利用していますが Supabase ではリレーショナルデータベースの Postgres データベースを利用しています。2 つのサービスには共通点もあり Firebase がデータベース以外にも認証機能やストレージ機能を持っているように Firebase の Alternative ということで Supabase も認証機能やストレージ機能を持っています。

supabaseトップページ
supabase公式サイトのトップページ

本文書では Supabase ではどのようにテーブルを作成し作成したテーブルに挿入したデータを Vue.js と React からどのように取得するのかを確認します。また認証機能はデフォルトではどのように設定されておりユーザ登録はどのように行うのかなど Supabase を利用するために必要となる基本的なことを中心に確認しています。

プラン

Supabase には Free, Pro ,Team, Enterprise の 4 つのプランがあります。動作確認のために利用するので Free プランを利用します。プランによって利用できるデータベースの容量や帯域、認証のユーザ数などに制限があります。プランについては公式のドキュメントの Pricingに記載されています。

サインインの設定

Supabase を利用するためにはサインアップを行う必要があります。サインアップを行う場合は GitHub のアカウントかメールアドレスを利用して行います。

画面中央から右上にある”Start your project”ボタンをクリックします。

supabaseトップページ
Start your project ボタンをクリック

サインイン画面にリダイレクトされた場合はまだアカウントを持っていないのでサインインすることができません。下記にある”Sign Up Now”をクリックしてください。

サインアップ画面
サインイン画面

サインアップ画面が表示されます。GitHub かメールアドレスでサインアップすることができます。

サインアップ画面
サインアップ画面

本文書では GitHub のアカウントを利用するので”Continue with Github”ボタンをクリックします。

GitHub アカウントによる Supabase の認証画面が表示されるので GitHub アカウントでサインインすることに問題がなければ”Authorize supabase”ボタンをクリックしてください。

GitHubアカウントとの連携
GitHubアカウントとの連携

GitHubのアカウントでのサインインが完了したら管理画面が表示されます。画面の中央には”New Project”ボタンがあります。

プロジェクト作成画面
プロジェクト作成画面

プロジェクトの作成

サインイン直後ではプロジェクトが存在しないのでプロジェクトの作成を行います。

プロジェクトの作成
プロジェクトの作成ボタンの表示

プロジェクトの名前、データベースのパスワード、Region の設定を行います。プロジェクトの名前は Test とし Database Password では”Generate a password”をクリックして協力なパスワードを設定します。パスワードは重要なので Copy ボタンをクリックして保存します。 Region には日本を選択することができるので Northeast Asia(Tokyo)を設定します。入力が完了したら右下にある”Create new project”ボタンをクリックします。

プロジェクトの作成
プロジェクトの作成

“Create new project”ボタンを押すとプロジェクトの画面が表示されます。ボタンを押した直後はプロジェクト名(Test)の右側に”Setting up project”と表示されプロジェクトの作成に少し時間がかかります。

プロジェクト作成直後の画面
プロジェクト作成直後の画面

プロジェクトの作成が完了した画面には Database をメインに Authentification, Storage に加えて Edge Function, Realtime が表示されています。

プロジェクト作成完了後の画面
プロジェクト作成完了後の画面

データベースの作成

Database, Auth, Storage とメニューが並んでいますが作成したテーブルにアクセスして中身を表示させる方法が知りたいと思っている読者の方も多いかと思いますので最初に Database の設定を行ってみましょう。左のサイドメニューの Home のアイコンの下にある Table Editor をクリックします。

Table Editorをクリック
Table Editorをクリック

デフォルトではテーブルは存在しないのでテーブルを新規で作成するため”Create a new table”ボタンをクリックします。

ボタンが表示
ボタンが表示

“Create a new table”をクリックするとテーブルの名前を入力する画面が表示されます。既に列にはidとcreated_atが設定されていることがわかります。

テーブルの作成画面
テーブルの作成画面

名前にはtodos、Descriptionにはテーブルの説明を入力し列にはtaskを追加した列の型をTextに設定しています。Enable Row Level Securityのチェックボックスがありますが”Recommended”と表示されているのでチェックを入れておきます。Row Level Securityはテーブルの列に対してアクセス制限を行うことができる機能です。

テーブルの作成
テーブルの作成

“Save”ボタンをクリックしてテーブルの作成を行います。テーブル作成後に”Insert row”ボタンが表示されているようにTable editorでは GUIにより行の追加が行えることがわかります。

テーブルの作成完了
テーブルの作成完了

テーブルにデータを挿入するために”insert row”ボタンをクリックとドロップダウンメニューにより”Insert row”, “Insert column”, “Import data from CSV”が表示されます。一番上の”Insert row”を選択します。

Insert rowボタンのクリック
Insert rowボタンのクリック

Optional Fields の task にテキストを入力します。id は”Automatically generated as identify”と表示されており行が追加されると自動で設定されます。created_at の時刻はデフォルト値が now()となるため設定しなければ自動で現在時刻が設定されます。

列の登録画面
行の登録画面

“Save”ボタンをクリックするとテーブルに行が追加されました。

行の追加
行の追加

supabase上にtodoテーブルを作成してデータを挿入することができました。

フロントエンドからのアクセス

Vue.js と React を利用してアクセス方法を確認します。

Vue.js からのアクセス

Vue.js を利用して supabase に作成したテーブルにアクセスする方法を確認します。Vue.js を利用するために”npm create vue@latest”コマンドを利用してプロジェクトの作成を行います。プロジェクト名は任意の名前をつけることができるのでここでは vue-supabase としています。インストール中にプロジェクトで利用する機能を選択することができますがここではすべてデフォルトの”No”を選択しています。


 % npm create vue@latest

Vue.js - The Progressive JavaScript Framework

✔ Project name: … vue-supabase
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit Testing? … No / Yes
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No / Yes

Scaffolding project in /Users/mac/Desktop/vue-supabase...

Done. Now run:

  cd vue-supabase
  npm install
  npm run dev

作成されるプロジェクトフォルダに移動してnpm installコマンドを実行します。


 % cd vue3_supabase
 % npm install

supabaseを利用するためにsupabase-jsライブラリのインストールを行います。


 % npm install @supabase/supabase-js

インストールが完了したら package.json を確認しておきます。


{
  "name": "vue-supabase",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@supabase/supabase-js": "^2.38.4",
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.4.0",
    "vite": "^4.4.11"
  }
}

.env ファイルをプロジェクトフォルダの直下に作成して環境変数の設定を行います。

環境変数には URL とキーの設定を行います。API のキーについては左側のサイドメニューにある Setting から API をクリックすることで確認することができます。

URLとAPIキーの確認
URLとAPIキーの確認

anon にあるキーをコピーして.env ファイルの VITE_SUPABASE_ANON_KEY に設定し URL を VITE_SUPABASE_URL に設定します。


VITE_SUPABASE_URL=YOUR_SUPABASE_URL
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY

src フォルダ直下に supabase.js ファイルを作成して以下の初期設定を記述します。.env ファイルに記述した環境変数は Vite では import.meta.env.環境変数名でアクセスすることができます。


import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

supabaseからデータ取得

App.vue ファイルに getTasks 関数を追加して supabase からデータが取得できるか確認を行います。


<script setup>
import { supabase } from './supabase';

const getTasks = async () => {
  let {
    data: todos,
    error,
    status,
  } = await supabase.from('todos').select('task');

  console.log(todos);
  console.log(error);
  console.log(status);
};

getTasks();
</script>

<template>
  <div>
    <h1>Vue3でsupabase</h1>
  </div>
</template>

突然 supabase の from メソッドが出てきましたが select などの SQL 文の書き方については左側のメニーの API Docs をクリックして、 Tables and Views にあるテーブル名をクリックすると右側に select 文や insert 文などの記述方法を確認することができます。

API Docsの確認
API Docsの確認

拡大すると Todo テーブルから task 列の値のみ取得したい場合は以下のコードを記述することになります。

Select Task
Select Task

npm run dev コマンドを実行して動作確認を行います。もし VITE_SUPABASE_ANON_KEY のキーに誤りがある場合には”Invalid authentication credentials”のメッセージが戻されます。

デベロッパーツールのコンソールを見ると戻されるデータにエラーがなくステータスが 200 になっていますがデータは入っていません。

コンソールの確認
コンソールの確認

初めて動作確認をするとどうしたらいいのかわからない人もいるかと思いますが原因はテーブル作成時にチェックを入れた Row Level Security です。Row Level Security が有効になっているため現在の状態でデータを取得するためには Enable から Disable にする必要があります。

テーブル作成時にRow Level Securityにチェックを入れていない場合はコンソールに取得したデータが表示されます。
fukidashi

Disable にするためには左側の Authentication をクリックして Polies を選択します。todos のテーブル名の横に”RLS enabled”が表示されていることが確認できます。

Polies から RLS Enabled の確認
Polies から RLS Enabled の確認

データを取得するために”Disable RLS”ボタンをクリックしてください。Disable の処理が反映されると”RLS diabled”になることが確認できます。

RLS disabled
RLS disabled

変更後コンソールを確認するとテーブルに保存されているデータを確認することができます。

RLS disabled後のコンソールの確認
RLS disabled後のコンソールの確認

Table Editor を利用してもさらにデータを追加してコンソールではなくブラウザ上に表示させてみましょう。取得したデータを reactive なデータ tasks に保存するため ref 関数を利用します。select の引数には列名ではなく”\*”を設定することですべての列を取得することができます。


<script setup>
import { ref } from 'vue';
import { supabase } from './supabase';

const tasks = ref([]);

const getTasks = async () => {
  let { data: todos, error, status } = await supabase.from('todos').select('*');

  tasks.value = todos;
};

getTasks();
</script>

<template>
  <div>
    <h1>Vue3でsupabase</h1>
    <ul>
      <li v-for="task in tasks" :key="task.id">{{ task.task }}</li>
    </ul>
  </div>
</template>

ブラウザ上には2件のtaskが表示されます。supabaseのテーブルに保存されているデータの取得方法を理解することができました。

ブラウザ上での表示
データベースに保存されたデータのブラウザ上での表示

RLS を Disabled にした状態ですが、Supabase に保存されたタスク情報を Vue.js から取得してブラウザ上に表示させることができました。

Reactからのアクセス

React を利用して supabase に作成したテーブルにアクセスする方法を確認します。”npm create vite@latest” コマンドを利用して React のプロジェクトの作成を行います。プロジェクト名に react-supabase を設定していますが任意の名前をつけてくだい。フレームワークの選択では React, variant では JavaScript を選択しています。


 % npm create vite@latest
Need to install the following packages:
create-vite@5.0.0
Ok to proceed? (y) y
✔ Project name: … react-supabase
✔ Select a framework: › React
✔ Select a variant: › JavaScript

Scaffolding project in /Users/mac/Desktop/react-supabase...

Done. Now run:

  cd react-supabase
  npm install
  npm run dev

プロジェクトの作成が完了すると react-supabase ディレクトリが作成されるので移動を行い、npm install コマンドを実行します。


 % cd react-supabase

supabaseを利用するためにsupabase-jsライブラリのインストールを行います。


 % npm install @supabase/supabase-js

インストールが完了したら.envファイルをプロジェクトフォルダの直下に作成して環境変数の設定を行います。

環境変数にはURLとキーの設定を行います。APIのキーについては左側のサイドメニューにあるSettingからAPIをクリックすることで確認することができます。

URLとAPIキーの確認
URLとAPIキーの確認

anon にあるキーをコピーして.env ファイルの VITE_SUPABASE_ANON_KEY に設定し URL を VITE_SUPABASE_URL に設定します。


VITE_SUPABASE_URL=YOUR_SUPABASE_URL
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
YOUR_SUPABASE_URL と YOUR_SUPABASE_ANON_KEY の値は各自が Supabase の管理画面から取得した値を設定してください。
fukidashi

src フォルダ直下に supabaseClinet.js ファイルを作成して以下の初期設定を記述します。


import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

supabaseからのデータの取得

App.jsx ファイルで import した useEffect Hook の中に getTasks 関数を追加して supabase からデータが取得できるか確認を行います。


import { useEffect } from 'react';
import { supabase } from './supabaseClient';

function App() {
  useEffect(() => {
    const getTasks = async () => {
      let {
        data: todos,
        error,
        status,
      } = await supabase.from('todos').select('task');

      console.log(todos);
      console.log(error);
      console.log(status);
    };
    getTasks();
  }, []);
  return (
    <div>
      <h1>Reactでsupabase</h1>
    </div>
  );
}

export default App;

突然 supabase の from メソッドが出てきましたが select などの SQL 文の書き方については左側のメニーの API Docs をクリックして、 Tables and Views にあるテーブル名をクリックすると右側に select 文や insert 文などの記述方法を確認することができます。

API Docsの確認
API Docsの確認

開発サーバを起動するために npm run dev コマンドを実行して動作確認を行います。もし VITE_SUPABASE_ANON_KEY のキーに誤りがある場合にはコンソールに下記のエラーメッセージが表示されます。


{
    "message": "Invalid API key",
    "hint": "Double check your Supabase `anon` or `service_role` API key."
}

デベロッパーツールのコンソールを見ると戻されるデータにエラーがなくステータスが 200 になっていますがデータは入っていません。

コンソールに表示される内容
コンソールに表示される内容

初めて動作確認をするとどうしたらいいのかわからない人もいるかと思いますが原因はテーブル作成時にチェックを入れた Row Level Security です。Row Level Security が有効になっているため現在の状態でデータを取得するためには Enable から Disable にする必要があります。

テーブル作成時にRow Level Securityにチェックを入れていない場合はコンソールに取得したデータが表示されます。
fukidashi

Disable にするためには左側の Authentication をクリックして Polies を選択します。todos のテーブル名の横に”RLS enabled”が表示されていることが確認できます。

Polies から RLS Enabled の確認
Polies から RLS Enabled の確認

データを取得するために”Disable RLS”ボタンをクリックしてください。Disable の処理が反映されると”RLS diabled”になることが確認できます。

RLS disabled
RLS disabled

変更後コンソールを確認すると0: {task: ‘ブログを書く’}を確認することができます。

RLS disabled後のコンソールの確認
RLS disabled後のコンソールの確認

Table Editor を利用してもさらにデータを追加してブラウザ上に表示させてみましょう。取得したデータを保存するために useState Hook を利用します。select の引数には列名ではなく”\*”を設定することですべての列を取得することができます。


import { useState, useEffect } from 'react';
import { supabase } from './supabaseClient';

function App() {
  const [tasks, setTasks] = useState([]);
  useEffect(() => {
    const getTasks = async () => {
      let {
        data: todos,
        error,
        status,
      } = await supabase.from('todos').select('*');
      setTasks(todos);
    };
    getTasks();
  }, []);
  return (
    <div>
      <h1>Reactでsupabase</h1>
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>{task.task}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

ブラウザ上には 2 件の task が表示されます。supabase のテーブルに保存されているデータの取得方法を理解することができました。

supabase に保存されたデータをブラウザに表示
supabase に保存されたデータをブラウザに表示

RLSについて

テーブルを作成する際に設定した Row Level Security を disabled にすることでデータを取得することができました。

Row Level Security は supabase の機能ではなく Postgres の機能です。Row Level Security という名前の通り Row(行)レベルのセキュリティに関する設定でアクセス制御を行うことができます。
fukidashi

Row Level Security を enabled にしてデータを取得できるようにするためには Policy の設定が必要となります。Authentication の Policies から”RLS enabled”になっていることを確認してください。もしなっていない場合には enabled にしてください。

RLS の設定の画面をよく見ると”New Policy”ボタンや “No policies created yet” のメッセージを確認することができます。メッセージから Policy が何も設定されていないことがわかります。つまりこの状態ではテーブルのデータのアクセスを行うことができません。

RLSの設定の確認
RLSの設定の確認

新しく Policy を追加するため”New Policy”ボタンをクリックします。Get started quickly と For full customization の 2 つから選択することができますが Get started quickly を選択します。Get started quickly では事前に用意されているテンプレートを利用することができますが For full customization ではスクラッチでポリシーを設定する必要があります。

Policyの追加画面
Policyの追加画面

Policy のテンプレートが表示されるので Enable read access to everyone を利用するために画面に右下に表示される”Use this template”ボタンをクリックします。

policy template を選択する
policy template を選択する

“Use this template”を選択するとPolicy名の設定やどのSQLの処理に適用するかも設定することができます。そのままの設定で画面右下に表示されている”Review”ボタンをクリックします。

Policy の各種設定
Policy の各種設定

次の画面では create policy による SQL 文を確認することができます。”Save Policy”ボタンをクリックすると Policy が設定されます。

Review で実際に適用される SQL を確認
Review で実際に適用される SQL を確認

作成したPolicyがRLSの画面に表示されます。

作成した Policy の表示
作成した Policy の表示

すべてのユーザがアクセスできるPolicyを設定したのでRLS enabledの状態でもVue/Reactどちらでもデータを取得してブラウザ上にTaskの一覧が表示されます。

認証機能

Supabase はデータベースを利用できるだけでなく認証機能を持っているのでどのように利用することができるの確認していきます。

左側のメニューから Authentification を選択すると登録するユーザの一覧を確認することができます。デフォルトではユーザは存在しないので”No users in your project yet”というメッセージを確認することができます。

Authenticationのユーザ確認
Authenticationのユーザ確認

ユーザの認証はクラウドサービスを利用して行うこともできます。Authentication の Configuration の Providers メニューをクリックすると Auth Providers の一覧を確認することができます。デフォルトでは Email のみ”Enabled”になっています。

Auth Providers一覧
Auth Providers一覧
Email認証の設定項目
Email認証の設定項目

### ユーザの登録

ユーザの登録

デフォルトの認証設定のまま supabase のライブラリが持つ auth.signUp メソッドを利用してユーザの登録ができるか確認します。通常は入力フォームが必要ですが動作確認のため直接メールアドレスとパスワードを設定しています。ユーザの登録を行うために user テーブルを作成する必要はありません。

Vue.js の場合

Vue の場合は App.vue ファイルに signInUser 関数を追加して実行します。signUp の引数のオブジェクトには email と password プロパティを設定します。ここでは emil にjohn@gmail.comを設定していますがメールが受信できるメールアドレスを指定してください。


const signUpUser = async () => {
  const { user, session, error } = await supabase.auth.signUp({
    email: 'john@gmail.com',
    password: 'password',
  });
  console.log(user);
  console.log(session);
  console.log(error);
};
signUpUser();

React の場合

React の場合は App.js ファイルの useEffect Hook の中に signUpUser 関数を追加して実行します。signUp の引数のオブジェクトには email と password プロパティを設定します。ここでは emil にjohn@gmail.comを設定していますがメールが受信できるメールアドレスを指定してください。


const signUpUser = async () => {
  const { user, session, error } = await supabase.auth.signUp({
    email: 'john@gmail.com,
    password: 'password',
  });
  console.log(user);
  console.log(session);
  console.log(error);
};

signUpUser();

ブラウザで localhost:3000 にアクセスすると signInUser 関数が実行され Authentification のユーザ一覧には登録したユーザの Email アドレスと User の UID を確認することができます。ブラウザを広げないと見えませんがその他に Provider、Created, Last Sign In などの列があります。

登録したユーザの確認
登録したユーザの確認

ユーザ登録と同時にConfigurationのSettingsの”Enable email confirmations”を設定しているので以下のメールの内容で送信されます。

Confirmationメールの内容
Confirmationメールの内容

送信されるメールの内容はAuthentificationのTemplatesで確認することができます。

テンプレートの確認
テンプレートの確認

画面に表示されている SMS Message, Confirmation Signup 以外にスクロールすると Reset Password, Magic Link, Change email address, Invite user のテンプレートがあります。

User 一覧の Last Sign In 列には”Waiting for verification..と表示されます。

Confirm your mail のリンクをクリックする Setting に設定されていた Site URL にリダイレクトされ User 一覧の Last Sign In 列に時刻が設定されます。また SignIn が行われるとブラウザのローカルストレージに supabase.auth.token のキーを持つ Token が保存されます。

Confirm your mailのリンクをクリックしていない状態でsignInを行おうとするとエラーメッセージとステータス{message: ‘Email not confirmed’, status: 400}が戻されます。
fukidashi

supabseにユーザを登録する方法を理解することができました。別記事でsupabaseが持つauth.signUpメソッド以外のメソッドを利用して認証方法を確認していく予定です。