I'm using Supabase Auth for user authentication and have a PostgreSQL schema with Row-Level Security enabled. Users are able to log in through my React web app without any issues. However, when they attempt to submit data—specifically inserting a new report into the Reports table—the request fails with a 400 Bad Request from the REST API.
Here's the core part of my database design:
Relevant Table Definitions
-- Users Table
CREATE TABLE Users (
user_id SERIAL PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100) UNIQUE NOT NULL,
role VARCHAR(20) DEFAULT 'citizen',
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Reports Table
CREATE TABLE Reports (
report_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES Users(user_id),
report_name VARCHAR(100),
latitude DECIMAL(9,6),
longitude DECIMAL(9,6),
description TEXT,
problem_type VARCHAR(50) NOT NULL,
status VARCHAR(50) DEFAULT 'new',
photo VARCHAR(255),
date_submitted TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
RLS Policy Example
CREATE POLICY "user can insert their own reports"
ON Reports
FOR INSERT
USING (
current_setting('app.current_user_id')::integer = user_id
);
My assumption is that Supabase would inject the current user's ID into the session so this policy would work, but it seems like either the app.current_user_id isn’t set, or the type mismatch between UUIDs from Supabase Auth and SERIAL integers in my Users table is causing the policy to block the request.
Frontend Code (React + Supabase)
In the form submit handler:
const report = {
user_id: user.id, // from supabase.auth.getSession()
report_name: formData.name,
latitude: position.lat,
longitude: position.lng,
description: formData.details,
problem_type: formData.type,
photo: imageUrl,
status: 'new',
date_submitted: new Date().toISOString()
};
const { error } = await supabase.from('Reports').insert([report]);
Despite the session appearing valid and user.id being set, the request returns 400 with no clear detail.
What I'm trying to achieve:
I want authenticated users to be able to create records (like reports) tied to their identity. What's the best way to structure this considering RLS? Do I need to switch to UUIDs for the Users.user_id to match auth.uid()? Or is there a way to make this work with integer IDs?
Any guidance on correctly configuring RLS or transforming session variables for integer user IDs would be appreciated.
CREATE POLICYstatement you wrote causes an error:only WITH CHECK expression allowed for INSERT. I recommend that you try running interactive SQL first, so that you get reasonable error messages rather than a meaningless HTTP error (I guess the error handling in your code should be improved). If that isn't enough for you to figure out the cause of the problem, including your findings in this question would make it possible for someone to answer it.