You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已登录Supabase却无法向开启RLS的profiles表插入数据是什么原因?

问题原因
  • 核心问题是调用supabase.auth.signUp成功拿到返回的user对象时,Supabase客户端的auth会话还未完成同步更新,此时发起数据库插入请求携带的仍是未登录状态的匿名令牌,数据库执行RLS校验时auth.uid()返回值为null,和插入的id字段不匹配,触发规则校验失败。
  • 如果项目开启了邮箱确认配置,用户注册成功后不会自动登录,客户端始终为匿名状态,也会触发相同报错。
解决方案

方案1:等待会话同步后执行插入

修改注册成功后的逻辑,先确认当前会话已生效再调用插入方法:

if(error){
  alert("Error signing in");
} else {
  // 等待会话同步完成
  const { data: { session } } = await supabase.auth.getSession()
  // 确认会话存在且用户ID匹配再执行插入
  if(session && session.user.id === user.id) {
    await addUserDetails({
      uuid: user.id, 
      firstName: firstNameRef.current.value, 
      lastName: lastNameRef.current.value
    });
    navigate("/dashboard");
  }
}

如果开启了邮箱确认,不建议使用该方案,优先选方案2。

方案2:使用数据库触发器自动创建profile(更推荐)

在数据库层面创建触发器,当auth.users表新增用户时自动向public.profiles表插入初始化数据,完全避开前端会话同步问题,且触发器执行不触发RLS校验:

-- 创建触发器函数
create function public.handle_new_user() 
returns trigger as $$
begin
  insert into public.profiles (id, first_name, last_name)
  values (new.id, new.raw_user_meta_data->>'first_name', new.raw_user_meta_data->>'last_name');
  return new;
end;
$$ language plpgsql security definer;

-- 给auth.users表绑定插入触发器
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute function public.handle_new_user();

使用该方案时需要把姓名参数传到signUp的options.data字段里,示例如下:

const {user, error} = await signUp({
  email, 
  password,
  options: {
    data: {
      first_name: firstNameRef.current.value,
      last_name: lastNameRef.current.value
    }
  }
});

配置完成后可以删掉前端的addUserDetails调用,注册成功后直接跳转页面即可。

内容的提问来源于stack exchange,提问作者jm123456

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 15:36:01