When providing a .select modifier that points to a foreign table, values fail to decode. I'm wondering if this is an issue in the way I'm declaring my select query, something to do with postgres or a bug in Supabase.
From what I can see, it looks as though value is decoding the wrong JSON string. If I look at the actual network response, the account value is an object, however the decoder thinks it is a string (presumably the foreign key in postgres). On the left you can see the raw API response, and on the right you can see what Supabase is trying to decode.
To Reproduce
Models
struct Transaction: Codable {
var id: UUID
var name: String
var subtitle: String?
var merchant: String?
var amount: Decimal
var tax_deductible: Bool = false
var date: Date
var account: TransactionAccount?
}
enum AccountType: String, Codable, CaseIterable {
case debit
case savings
case loan
case credit
case cash
}
struct TransactionAccount: Codable, Hashable {
var id: UUID
var name: String
var description: String?
var type: AccountType
var color: String
}
SDK Usage
do {
return try await Database.shared
.client
.database
.from("transactions")
.select("*, account(*)")
.in("type", value: scope.transactionTypes.map({ $0.rawValue }))
.execute()
.value
} catch {
return []
}
Swift Error
Printing description of error:
▿ DecodingError
▿ typeMismatch : 2 elements
- .0 : Swift.Dictionary<Swift.String, Any>
▿ .1 : Context
▿ codingPath : 2 elements
▿ 0 : _JSONKey(stringValue: "Index 2", intValue: 2)
▿ rep : Rep
- index : 2
- 1 : CodingKeys(stringValue: "account", intValue: nil)
- debugDescription : "Expected to decode Dictionary<String, Any> but found a string instead."
- underlyingError : nil
Expected behavior
The docs make it clear that I should be able to do this and get back the full object from the foreign table. https://supabase.com/docs/reference/swift/select?example=querying-foreign-table-with-count
Additional context
If I add every value to my query individually, the request works as expected:
do {
return try await Database.shared
.client
.database
.from("transactions")
.select(
"""
id,
description,
amount,
type,
date,
name,
tax_deductible,
account(*)
"""
)
.in("type", value: scope.transactionTypes.map({ $0.rawValue }))
.execute()
.value
} catch {
return []
}
}
