workinprogress98
workinprogress98

Reputation: 115

Supabase RPC functions return 204 every time, but don't update table

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

Answers (3)

Simon
Simon

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

dshukertjr
dshukertjr

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

workinprogress98
workinprogress98

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

Related Questions