Supabase Kotlin查询返回空列表,同SQL在编辑器中正常
问题:Supabase Kotlin库查询返回空列表,但SQL编辑器执行正常
我尝试用Supabase Kotlin库从Table_User_Scans表获取特定user_id的最新扫描数据,查询返回空列表,但相同逻辑的SQL在Supabase SQL编辑器里能正常返回结果。
我的代码与配置
Kotlin查询代码
val userId = "<USERID>" val latestScanData = withContext(Dispatchers.IO) { supabase.from("Table_User_Scans") .select() { filter { eq("user_id", userId) } order(column = "ScanTimeStamp", order = Order.DESCENDING) limit(count = 1) } .decodeSingle<UserScans>() }
表结构
| Name | Description | Data Type |
|---|---|---|
user_id | - | uuid |
UserName | - | character varying |
ScanTimeStamp | - | timestamp without time zone |
FrontFaceImageUrl | - | character varying |
SideFaceImageUrl | - | character varying |
ApiJsonOutput | - | json |
Kotlin数据类
package com.indiedev91.looksmaxeai_bebetterversion.Utils import kotlinx.serialization.Serializable @Serializable data class UserScans( val user_id: String, val UserName: String, val ScanTimeStamp: String, val FrontFaceImageUrl: String, val SideFaceImageUrl: String, val ApiJsonOutput: String? )
可正常运行的SQL查询
SELECT * FROM "Table_User_Scans" WHERE user_id = '<USERID>' ORDER BY "ScanTimeStamp" DESC LIMIT 1;
我已经检查过列名匹配、数据类与表结构对应、遵循官方文档,但问题依旧。
可能的问题点与调试步骤
1. 表名/列名的大小写处理
PostgreSQL对大小写敏感,若表/列创建时使用了双引号(如你的"Table_User_Scans"和"ScanTimeStamp"),客户端查询时必须保留大小写。Supabase Kotlin客户端默认会将标识符转为小写,导致找不到对应的表/列。
修复方式:在查询时用双引号包裹表名和列名:
supabase.from("\"Table_User_Scans\"") .select() { filter { eq("user_id", userId) } order(column = "\"ScanTimeStamp\"", order = Order.DESCENDING) limit(count = 1) }
2. UUID类型匹配问题
数据库中user_id是uuid类型,Kotlin代码中用String传递值时,若格式不正确(比如多余的空格、非标准UUID格式),会导致匹配失败。
验证方式:
- 确保
userId是标准UUID字符串(如"550e8400-e29b-41d4-a716-446655440000") - 尝试将
userId转为UUID对象再传递:import java.util.UUID val userId = UUID.fromString("<USERID>") filter { eq("user_id", userId) }
3. Row Level Security(RLS)权限问题
SQL编辑器使用的是超级用户权限,而Kotlin客户端使用的是前端用户/匿名用户权限,若RLS策略限制了该用户的查询权限,会返回空结果。
检查方式:
- 在Supabase控制台进入
Table_User_Scans表的“权限”页面,查看RLS策略是否允许当前客户端用户查询该数据 - 临时关闭RLS测试:执行
ALTER TABLE "Table_User_Scans" DISABLE ROW LEVEL SECURITY;,再运行Kotlin代码,若能返回数据,说明是RLS策略问题
4. 序列化/解码异常
虽然你检查了数据类,但ScanTimeStamp是数据库timestamp类型,Kotlin中用String接收可能存在序列化格式不匹配的问题,导致解码失败(表面上返回空,实际是解码异常被吞)。
修复方式:
- 将
ScanTimeStamp类型改为Instant或LocalDateTime,并确保序列化配置支持:import kotlinx.serialization.Serializable import java.time.Instant @Serializable data class UserScans( val user_id: String, val UserName: String, val ScanTimeStamp: Instant, val FrontFaceImageUrl: String, val SideFaceImageUrl: String, val ApiJsonOutput: String? )
5. 查看客户端实际发送的SQL
开启Supabase Kotlin客户端的日志,查看生成的SQL是否与手动执行的一致,定位差异点。
配置日志:在项目的logback.xml或相关日志配置中添加:
<logger name="io.github.jan.supabase" level="DEBUG"/>
运行代码后,查看日志中打印的SQL语句,对比手动执行的SQL是否有差异。
内容的提问来源于stack exchange,提问作者Player91
相关产品推荐
相关产品推荐

