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

使用Supabase与SvelteKit时,开启RLS后查询返回空数组问题

问题分析与解决方案

你的问题核心是:RLS策略在Supabase Studio模拟认证用户时正常,但前端SvelteKit代码查询返回空数组,切换到anon角色并开放权限时能返回数据。这说明前端请求没有以authenticated角色发送,或者用户会话未正确传递。

以下是具体排查和解决步骤:

1. 确认前端用户已正确登录,会话有效

在调用查询函数前,先检查当前用户的会话状态,确保请求是在用户登录后发送的:

export const readAllClients = async () => {
  // 先获取当前会话
  const { data: { session } } = await supabase.auth.getSession();
  
  if (!session) {
    console.log("用户未登录,请求将以anon角色发送");
    clients.set([]);
    return;
  }
  
  // 打印当前用户ID,和client表中的userId对比是否一致
  console.log("当前认证用户ID:", session.user.id);

  const { data, error } = await supabase
    .from("client")
    .select("*, invoice(id, invoiceStatus, lineItems(*))");

  if (error) {
    console.error(error);
    return;
  }

  clients.set(data as Client[]);
};

如果打印出"用户未登录",说明前端没有正确处理登录流程,需要确保用户完成登录后再调用查询函数。

2. 检查RLS策略的列匹配与类型一致性

  • 确认client表中的userId列类型是uuid(和auth.users.id的类型一致),如果类型不匹配(比如存成了字符串),auth.uid()返回的uuid和userId无法匹配,会导致无数据返回。
  • 确认策略中的列名正确:如果你的列名是驼峰式的userId,必须用双引号包裹("userId"),否则PostgreSQL会自动转为小写userid;如果表中列名实际是userid,则需要修改策略为auth.uid() = userid。

3. 确认Supabase客户端的上下文(服务端/客户端差异)

如果你的查询是在SvelteKit的服务端(比如+page.server.ts的load函数)调用的,不能直接用客户端初始化的supabase实例,需要用@supabase/auth-helpers-sveltekit提供的getSupabase函数获取带用户会话的客户端:

// +page.server.ts
import { getSupabase } from '@supabase/auth-helpers-sveltekit';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async (event) => {
  const { supabase } = await getSupabase(event);
  
  const { data, error } = await supabase
    .from("client")
    .select("*, invoice(id, invoiceStatus, lineItems(*))");
  
  if (error) {
    console.error(error);
    return { clients: [] };
  }
  
  return { clients: data };
};

服务端的supabase实例需要通过event获取用户会话,否则会以anon角色发送请求,触发RLS策略过滤掉所有数据。

4. 验证RLS策略的有效性

可以临时修改策略,添加指定用户UUID测试逻辑是否正确:

create policy "Allow users to select only the clients they created"
on client for select
to authenticated
using (
  auth.uid() = "userId"
  -- 临时添加,替换为你的测试用户UUID
  AND auth.uid() = '123e4567-e89b-12d3-a456-426614174000'
);

如果添加指定UUID后能返回数据,说明策略逻辑正确,问题出在前端的用户会话传递上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:15:54