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

Kotlin应用中更新Supabase int4字段无响应问题求助

Kotlin+Supabase更新int4字段导致原有更新逻辑失效问题

我在Kotlin应用中尝试更新Supabase的int4类型字段(staff_role和unit),但将这两个字段添加到更新映射后,原本正常工作的OnCallDates、GymCallDates、LeaveDates字段更新逻辑,包括else分支的通用字段更新,全部失效。不想把数据类型改成String,相关代码如下:

编辑员工数据函数

suspend fun editStaffData(context: Context, staff: StaffMember, imageBitmap: Bitmap?, fieldToEdit: String): Result<Unit> {
    return try {
        // 提供新图片时,上传并更新员工的imageUrl
        val updatedStaff = if (imageBitmap != null) {
            val imageUrl = uploadImage(context, imageBitmap, staff.id)
            staff.copy(imageUrl = imageUrl)
        } else {
            staff
        }

        when(fieldToEdit) {
            DatabaseField.OnCallDates.name -> {
                val updatedCallDates = updatedStaff.onCallDates.ifEmpty {
                    emptyList()
                }

                withContext(Dispatchers.IO) {
                    val client = getSupabaseClient()
                    client.from("staff")
                        .update(mapOf("on_call_dates" to updatedCallDates)) {
                            filter {
                                eq("id", staff.id)
                            }
                        }
                }
            }

            DatabaseField.GymCallDates.name -> {
                val updatedGymDates = updatedStaff.gymCallDates.ifEmpty {
                    emptyList()
                }

                withContext(Dispatchers.IO) {
                    val client = getSupabaseClient()
                    client.from("staff")
                        .update(mapOf("gym_call_dates" to updatedGymDates)) {
                            filter {
                                eq("id", staff.id)
                            }
                        }
                }
            }

            DatabaseField.LeaveDates.name -> {
                val updatedLeaveDates = updatedStaff.leaveDates.ifEmpty {
                    emptyList()
                }

                withContext(Dispatchers.IO) {
                    val client = getSupabaseClient()
                    client.from("staff")
                        .update(mapOf("leave_dates" to updatedLeaveDates)) {
                            filter {
                                eq("id", staff.id)
                            }
                        }
                }
            }

            else -> {
                withContext(Dispatchers.IO) {
                    val client = getSupabaseClient()

                    val updatedStaffMap = if (imageBitmap != null) {
                        mapOf(
                            "first_name" to staff.firstName,
                            "last_name" to staff.lastName,
                            "phone" to staff.phone,
                            "image_url" to staff.imageUrl
                        )
                    } else{
                        mapOf(
                            "first_name" to staff.firstName,
                            "last_name" to staff.lastName,
                            "phone" to staff.phone
                        )
                    }

                    client.from("staff")
                        .update( updatedStaffMap
                        ) {
                            filter { eq("id", staff.id) }
                        }
                }
            }
        }

        Result.success(Unit)
    } catch (e: Exception) {
        Result.failure(e)
    }
}

StaffMember数据类

@Serializable
data class StaffMember(
    @SerialName("id") val id: String = "",
    @SerialName("first_name") val firstName: String,
    @SerialName("last_name") val lastName: String,
    @SerialName("staff_role") val staffRole: Int,
    @SerialName("unit") val unit: Int,
    @SerialName("on_call_dates") val onCallDates: List<Pair<Int, List<Int>>> = emptyList(),
    @SerialName("gym_call_dates") val gymCallDates: List<Pair<Int, List<Int>>> = emptyList(),
    @SerialName("leave_dates") val leaveDates: List<Pair<Int, Int>> = emptyList(),
    @SerialName("phone") val phone: String,
    @SerialName("image_url") val imageUrl: String = ""
)

问题排查方向

  1. 序列化类型不兼容:Supabase客户端对Kotlin Int与PostgreSQL int4的序列化可能存在隐式冲突,混入Int字段后导致整个请求序列化失败,请求未被正确处理。
  2. 更新映射类型混合问题:原逻辑中日期字段用List类型,添加Int字段后,同一映射内类型混杂,触发客户端序列化bug,导致更新请求失效。
  3. 异常被静默吞掉:当前try-catch仅返回failure但未记录具体异常,可能序列化错误等问题未被发现,代码误以为执行成功。

解决方案

1. 显式确保Int字段序列化正确性

在更新映射中添加int字段时,确保类型匹配,同时检查Supabase客户端的序列化配置:
修改else分支的updatedStaffMap:

val updatedStaffMap = if (imageBitmap != null) {
    mapOf(
        "first_name" to staff.firstName,
        "last_name" to staff.lastName,
        "phone" to staff.phone,
        "image_url" to staff.imageUrl,
        "staff_role" to staff.staffRole,
        "unit" to staff.unit
    )
} else{
    mapOf(
        "first_name" to staff.firstName,
        "last_name" to staff.lastName,
        "phone" to staff.phone,
        "staff_role" to staff.staffRole,
        "unit" to staff.unit
    )
}

同时确认Supabase客户端使用kotlinx-serialization正确处理Int类型:

val supabase = createSupabaseClient(
    supabaseUrl = "你的Supabase地址",
    supabaseKey = "你的API密钥"
) {
    install(Postgrest) {
        serializer = KotlinxSerializer()
    }
}

2. 拆分更新请求

将int字段的更新与其他字段分开执行,避免同一请求内类型混杂:

else -> {
    withContext(Dispatchers.IO) {
        val client = getSupabaseClient()
        // 更新通用字段
        val baseMap = if (imageBitmap != null) {
            mapOf(
                "first_name" to staff.firstName,
                "last_name" to staff.lastName,
                "phone" to staff.phone,
                "image_url" to staff.imageUrl
            )
        } else {
            mapOf(
                "first_name" to staff.firstName,
                "last_name" to staff.lastName,
                "phone" to staff.phone
            )
        }
        client.from("staff")
            .update(baseMap) {
                filter { eq("id", staff.id) }
            }
        // 单独更新int字段
        client.from("staff")
            .update(mapOf("staff_role" to staff.staffRole, "unit" to staff.unit)) {
                filter { eq("id", staff.id) }
            }
    }
}

3. 添加异常日志定位问题

在catch块中打印异常详情,明确错误原因:

catch (e: Exception) {
    Log.e("StaffEditError", "员工数据更新失败", e)
    Result.failure(e)
}

4. 使用数据类直接更新

避免手动构建Map,直接用StaffMember对象更新,让客户端自动处理序列化:

// 在else分支中替换原更新逻辑:
client.from("staff")
    .update(updatedStaff) {
        filter { eq("id", staff.id) }
    }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:14:52