next.jsとsupabaseでコメントをリアルタイム表示するアプリを作る　その2

こんにちは。
今日も続きをやっていきます！

前回記事：
https://qiita.com/output_tarou/items/77c6b254adcc6551dff6

今回は作ったプロジェクトとsupabaseの接続を行います。

supabaseでは
settingメニューからDBのURLとanon keyが取得できるので、
それをプロジェクトのenvファイルに記述しました。

.env.localファイルを作成し、下記を記載します。
```
NEXT_PUBLIC_SUPABASE_URL=url
NEXT_PUBLIC_SUPABASE_ANON_KEY=anon_key
```
そしてsupabase側で新規テーブルを作成し、
テストデータも1件作ってみます。

テーブル名はcomments
カラムは下記の最低限です。
id int8 autoincrement primary
content varcher 
created_at time

supabaseではテストデータも直感的に作れるのが良いですね。

プロジェクト側で下記のような投稿のフォームと
更新があれば即時取得する一覧画面を作りました。

```
'use client';

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

interface Comment {
  id: number;
  content: string;
  created_at: string;
}

const Page = () => {
  const [comment, setComment] = useState<string>('');
  const [comments, setComments] = useState<Comment[]>([]);

  const fetchComments = async () => {
    const { data, error } = await supabase
      .from('comments')
      .select('*')
      .order('created_at', { ascending: false });

    if (error) console.error('Error fetching comments', error);
    else setComments(data);
  };

  useEffect(() => {
    fetchComments();
  }, []);

  const handleCommentSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const { data, error } = await supabase
      .from('comments')
      .insert([
        { content: comment }
      ]);

    if (error) console.error('Error submitting comment', error);
    else {
      setComment('');
      fetchComments();
    }
  };

  return (
    <div>
      <h1>Comments</h1>
      <form onSubmit={handleCommentSubmit}>
        <textarea
          value={comment}
          onChange={e => setComment(e.target.value)}
          placeholder="Write a comment..."
        />
        <button type="submit">Post Comment</button>
      </form>
      <div>
        {comments.map((comment) => (
          <div key={comment.id} style={{ border: '1px solid #ccc', padding: '10px', margin: '10px 0' }}>
            <p>{comment.content}</p>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Page;

```

また、supabaseのライブラリをインストールし、
supabaseクライアントを初期化するファイルもプロジェクトルートに作ります。

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

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

const supabase = createClient(supabaseUrl, supabaseAnonKey);

export default supabase;
```

これでlocalhost:3000で作ったテストデータが画面に表示されれば成功！
と思いましたが、エラーが出ました。

```
POST https://test.supabase.co/rest/v1/comments?columns=%22content%22 401 (Unauthorized)
rror submitting comment {code: '42501', details: null, hint: null, message: 'new row violates row-level security policy for table "comments"'}code: "42501"details: nullhint: nullmessage: "new row violates row-level security policy for table \"comments\""[[Prototype]]: Object
```

どうやらテストとしてsubmitしたのですが、
DBへの書き込み権限がないため、エラーになっていました。
（ついでに読み込み権限もないため、リスト表示もエラーになっていました。）

これの解決としては
supabase側でRow Level Security (RLS)のpolicyを作ってやる必要がありました。

selectの場合は下記を、
```
alter policy "Enable read access for all users"
on "public"."comments"
to public
using (
  true
);
```

insertの場合は下記ポリシーを作ってやれば、無事リストの表示とデータ挿入ができるようになりました！
```
alter policy "insert"
on "public"."comments"
to public
with check (
  true
);
```

今現在はこんな感じ。

![スクリーンショット 2024-06-14 20.49.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583082/3dc2b4db-e51d-67dc-8e95-839a23cb592e.png)

見た目やら表示内容やら、追加機能やら
やりたいことがいっぱい思い浮かぶので、
次回も引き続き、改良を加えていきます！