LoginSignup
1
1
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

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

Posted at

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

前回記事:
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

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1