티스토리 뷰

1. 문제 발생

포인트 지급 로직 구현을 위해 supabase 데이터를 업데이트 하는 과정에서 문제가 발생했다. 아무리 해도 supabase 데이터가 update가 되지 않는다. 

2. 접근 - 문제 해결

 2-1. 일단 console을 찍어 어디가 작동을 안하는지 알아봤다.

//ssr 또는 csr
'use client';
import { createClient } from '../../utils/supabase/client';
import { useEffect, useState } from 'react';

const PointStorePage = () => {
  const supabase = createClient();
  const [points, setPoints] = useState(0);

  useEffect(() => {
    //포인트 data 가져오기
    const getPoint = async () => {
      // const { data, error } = await supabase.from('auth').select('user_point');
      // console.log('슈퍼베이스 data', data);
      // const {
      //   data: { user }
      // } = await supabase.auth.getUser();
      // console.log('유저data', user);
      const { data, error } = await supabase.from('auth').select('user_point').eq('user_id', 1111);
      if (error) {
        console.error('Error fetching data getPoint : ', error.message);
      } else if (data) {
        console.log('유저 1111', data[0]?.user_point);
        setPoints(data[0]?.user_point);
        return data[0]?.user_point;
      }
    }; //params로 가져오기, middleware 써서 api 중 로그인한 사용자의 id 값 가져오는 api 있음
    //id값 하나 지정해서 가져오게 해서 사용하기
    getPoint();
  }, []);
//-----------------------------------업데이트
  useEffect(() => {
    const updatePoint = async () => {
      const { data, error } = await supabase.from('auth').update({ user_point: points }).eq('user_id', 1111);
      console.log('업데이트데이터 : ', data);
    };
    updatePoint();
  }, [points]);
//-----------------------------------
  const buyProduct = () => {
    setPoints(points - 1);
  };

  return (
    <>
      <div>내 포인트 : {points}</div>
      <button onClick={() => buyProduct()} className="border-solid border-2 border-black-600">
        상품, 포인트 차감 : 1p
      </button>
    </>
  );
};
export default PointStorePage;

- updatePoint 로직 자체는 point가 변경될 때 마다 잘 작동한다. setPoints도 잘 작동함. 문제는 data가 빈 배열을 뱉어내고 있다는 점이다. 아무래도 update 로직이 잘못되었거나 한 것 같은데 공식 문서를 봐도 영 잘못된 게 보이지 않는다. 도와줘요 구글!

구글링을 하다가 RLS 정책이라는 키워드가 눈에 띄었다. 잘 모르겠는데 한번 확인이나 해보자 싶어 확인하니

point가 있는 auth는 email 형식의 유저만 업데이트가 가능하다고 되어 있다. 진짜 이것 때문이었다니..!

auth의 정책을 바꾸려다 point가 auth 테이블에 있는 것 보단 따로 table을 만드는 것이 좋을 것 같다는 피드백을 받았어서, 이번 기회에 그냥 point 테이블을 새로 만들기로 했다. 

새로 테이블을 만들고 user_id를 연결, 이 값과 point 값 등을 새로 넣어주니 해결됐다. 

//ssr 또는 csr
'use client';
import { createClient } from '../../utils/supabase/client';
import { useEffect, useState } from 'react';

const PointStorePage = () => {
  const supabase = createClient();
  const [points, setPoints] = useState(0);

  useEffect(() => {
    //포인트 data 가져오기
    const getPoint = async () => {
      // const { data, error } = await supabase.from('auth').select('user_point');
      // console.log('슈퍼베이스 data', data);
      // const {
      //   data: { user }
      // } = await supabase.auth.getUser();
      // console.log('유저data', user);
      const { data, error } = await supabase
        .from('point')
        .select('user_point')
        .eq('user_id', '1fe39a95-d9dd-473b-9140-db0b978dfe2f');
      if (error) {
        console.error('Error fetching data getPoint : ', error.message);
      } else if (data) {
        console.log('유저 test', data[0]?.user_point);
        setPoints(data[0]?.user_point);
        return data[0]?.user_point;
      }
    }; //params로 가져오기, middleware 써서 api 중 로그인한 사용자의 id 값 가져오는 api 있음
    //id값 하나 지정해서 가져오게 해서 사용하기
    getPoint();
  }, []);

  useEffect(() => {
    const updatePoint = async () => {
      const { data, error } = await supabase
        .from('point')
        .update({ user_point: points })
        .eq('user_id', '1fe39a95-d9dd-473b-9140-db0b978dfe2f')
        .select('user_point');
      if (error) {
        console.error('Error updating data updataPoint : ', error.message);
      } else if (data) {
        console.log('업데이트 완료 : ', data);
      }
      console.log('업데이트데이터 : ', data); // 함수 정상 작동
    };
    updatePoint();
    console.log('Current points:', typeof points, points);
  }, [points]);

  const buyProduct = () => {
    setPoints(points - 1);
  };

  return (
    <>
      <div>내 포인트 : {points}</div>
      <button onClick={() => buyProduct()} className="border-solid border-2 border-black-600">
        상품, 포인트 차감 : 1p
      </button>
    </>
  );
};
export default PointStorePage;

로그인 기능이 구현되면 현재 userid를 가져와야 하는데, 그러려면 그 때 또 코드 수정이 필요하겠지만 일단 이걸로 테스트는 될 듯 하다. update 기능도 잘 동작한다. 

 

3. 회고

RLS 문제였는데 애먼 update 함수를 고치느라 시간을 많이 잡아먹었다. 그래도 공식문서랑 조금 더 친해졌다. RLS는 만져본 적 없어서 미루고 있었는데 겁먹지 말고 확인 빨리 할 수 있는 것은 빨리빨리 확인해버리는 것도 방법일 것 같다. 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함