I am trying to query my posts
table for a post, which contains the user’s user_id
and I want to join it with the profiles
table using the user_id
.
post table schema: (post_id: uuid, created_at: timestamptz, image_url: text, user_id: uuid, num_likes: integer, description: text)
My foreign key relation is set up on supabase with this table and profiles for the user_id
.
profiles table schema: (user_name: text, first_name: text, last_name: text, is_premium: boolean, user_id: uuid, num_posts: smallint, num_followers: integer, num_following: integer)
when trying to query the tables with:
const { data, error } = await supabase
.from("posts")
.select(
`post_id, created_at, image_url, user_id, num_likes, description, profiles ( user_id, user_name, first_name, last_name, num_followers, num_following, num_posts, is_premium )`
)
.limit(1)
.single();
I recieve no errors and I correctly receive a user’s profile information, but the data.profiles
is expected to be an array. However, it is not returning an array, it just returns a single object for data.profiles
.
sample of what the query is returning:
Object {
"created_at": "2023-07-29T15:54:53.849017+00:00",
"description": "This is a description",
"image_url": "NULL",
"num_likes": 3,
"post_id": "e0392738-5085-4026-9446-56e4bde69fee",
"profiles": Object {
"first_name": "John",
"is_premium": true,
"last_name": "Doe",
"num_followers": 0,
"num_following": 0,
"num_posts": 0,
"user_id": "108a1e53-1df6-4baf-a4ca-f0c445f085d2",
"user_name": "User123",
},
"user_id": "108a1e53-1df6-4baf-a4ca-f0c445f085d2",
}
but this is the expected type:
data: {
post_id: any;
created_at: any;
image_url: any;
user_id: any;
num_likes: any;
description: any;
profiles: {
user_id: any;
user_name: any;
first_name: any;
last_name: any;
num_followers: any;
num_following: any;
num_posts: any;
is_premium: any;
}[];
}
More Context:
Here is the unedited function that calls from supabase:
export const getNextPost = createAsyncThunk(
"getNextPost",
async (payload: {
lastPostCreatedAt: string;
}): Promise<(postsTableRow & { profiles: profilesTableRow }) | null> => {
const { data, error } = await supabase
.from("posts")
.select(
`post_id, created_at, image_url, user_id, num_likes, description, profiles ( user_id, user_name, first_name, last_name, num_followers, num_following, num_posts, is_premium )`
)
.order("created_at", { ascending: false })
.lt("created_at", payload.lastPostCreatedAt)
.limit(1)
.single();
if (error?.code === "PGRST116") return null;
if (error) console.warn(error);
console.log("DATA:", data);
return data as postsTableRow & { profiles: profilesTableRow };
}
);
if I change the return type from: Promise<(postsTableRow & { profiles: profilesTableRow }) | null>
to Promise<(postsTableRow & { profiles: profilesTableRow[] }) | null>
The compiler warning goes away but it still returns a profilesTableRow
not the expected profilesTableRow[]
2
Answers
As a workaround casting the result as an
unknown
and then to the correct type fixes the error. In my case I diddata?.profiles as unknown as profilesTableRow
so thatdata.profiles
is no longer expected to be an array (even though its already not an array).Seems like it's just a supabase bug
I found a much better solution:
It seems like generating types using the supabase cli seems to have also fixed this issue. Supabase docs: https://supabase.com/docs/guides/api/rest/generating-types