Reputation: 115
I'm in my backend (Node and Typescript). In my rpc function, Im just trying to append jsonb to a jsonb array:
BEGIN
UPDATE public.profile
SET checking_tokens = checking_tokens || input::JSONB
WHERE id = userid;
END;
Where userid holds the id of the authenticated user, and input holds a jsonb object. 'checking_tokens' is of type jsonb array as well.
In my backend, I have this snippet for actually invoking the above function :
try {
const {data, error} = await supabase.rpc('add_checking_account', {
input: {
[official_name]: { access, bank, code, id, subtype, 'date-added': today }
},
userid: userID
});
if (error) {
console.log("Error with add_checking_tokens:", error)
}
} catch (error) {
console.error('Error with rpc function:', error)
}
All the parameters do return their expected results as well, no problems there. In addition, I don't get any error messages and when checking the logs in my supabase account, the function does execute and returns a 204.
But, the table doesn't update.
I've also tried making up even basic functions that do as little as storing a string in some made-up column, but same issue. The response is a success though no changes to the table.
I've also made sure my URL and KEY are correct too. Any ideas?
Upvotes: 1
Views: 1369
Reputation: 2643
If you're seeing this issue — from their Discord channel:
RLS is silent from postgres for updates that don’t meet RLS. This is for security reasons. It is the same for Select.
No error, no data - it's annoying but I can see why they've done it. Check RBAC first, then triggers etc.
Upvotes: 1
Reputation: 18680
In order to update a row, the user needs to have not only update
permission, but select
permission as well. One way to fix this issue is to figure out where you went wrong with the policies.
Here is another way you could fix it too. You probably have userId
as the parameter of the rpc function, but you can remove the userId
parameter, and use auth.uid()
in its place. You can also make the function security definer so that the function can bypass RLS policies. Since auth.uid()
will always contain the caller user's user ID, it is safe in this case to make the function a security definer.
BEGIN
UPDATE public.profile
SET checking_tokens = checking_tokens || input::JSONB
WHERE id = auth.uid();
END;
Upvotes: 0
Reputation: 115
I discovered why. It happened to be caused by the RLS policies I had in place. Once I disabled them, I was able to update my table. Though now I have to work backwards to find what policy was giving me the problem in the first place.
Upvotes: 0