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

Supabase RPC函数返回全部用户数据而非指定用户问题排查

问题排查与解决

问题根源

你的SQL RPC函数参数名user_id与user_roles表的列名重复,导致WHERE子句中的user_id被PostgreSQL优先解析为user_roles.user_id列,而非函数传入的参数。由于JOIN条件已经是ur.user_id = p.id,WHERE条件等价于p.id = ur.user_id,相当于没有过滤,因此返回所有关联用户的数据。

解决方法

有两种可行的修复方式:

方式1:使用位置参数引用函数参数

直接用$1(代表第一个函数参数)代替参数名,避免列名冲突:

CREATE OR REPLACE FUNCTION public.get_profile_with_role(user_id uuid)
 RETURNS TABLE(
  id uuid,
  username text,
  name text,
  website text, 
  avatar_url text, 
  welcome_email_sent boolean, 
  has_accepted_privacy_policy boolean,
  country text,
  phone_number text,
  about_me text,
  gender text,
  city text,
  rut text,
  role_id integer
 )
 LANGUAGE sql AS
$func$
SELECT 
  p.id,
  p.username,
  p.name,
  p.website,
  p.avatar_url,
  p.welcome_email_sent,
  p.has_accepted_privacy_policy,
  p.country,
  p.phone_number,
  p.about_me,
  p.city,
  p.rut,
  ur.role_id
FROM 
profiles p
JOIN user_roles ur ON ur.user_id = p.id
WHERE p.id = $1  -- 用$1明确引用函数传入的第一个参数
$func$;

这种方式不需要修改前端代码,保持原调用逻辑即可。

方式2:修改函数参数名,避免与列名冲突

将函数参数名改为不与表列重复的名称,比如target_user_id,同时更新WHERE子句和前端调用的参数名:

修改后的RPC函数:

CREATE OR REPLACE FUNCTION public.get_profile_with_role(target_user_id uuid)
 RETURNS TABLE(
  id uuid,
  username text,
  name text,
  website text, 
  avatar_url text, 
  welcome_email_sent boolean, 
  has_accepted_privacy_policy boolean,
  country text,
  phone_number text,
  about_me text,
  gender text,
  city text,
  rut text,
  role_id integer
 )
 LANGUAGE sql AS
$func$
SELECT 
  p.id,
  p.username,
  p.name,
  p.website,
  p.avatar_url,
  p.welcome_email_sent,
  p.has_accepted_privacy_policy,
  p.country,
  p.phone_number,
  p.about_me,
  p.city,
  p.rut,
  ur.role_id
FROM 
profiles p
JOIN user_roles ur ON ur.user_id = p.id
WHERE p.id = target_user_id
$func$;

修改后的前端代码:

const getProfile = async() => {
    const user = supabase.auth.user();
    let {data, error, status} = await supabase.rpc('get_profile_with_role', {target_user_id: user.id});
    if(error) throw error;
    if(data && data.length > 0) {
      let cleanUserName = data[0].username ? data[0].username.replace(/['"]+/g, '') : '';
      setUserInfo(data[0]);
    }
  }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:27:11