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

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>()
}

表结构

NameDescriptionData 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:05:17