Supabase Failed Database Update not related (?) to RLS

I’ve been banging my head against the wall on this…

Some context:

  • I’m developing an ioS app
  • I have offloaded all Supabase interactions to a REST API built in NestJS
  • I have a user profile context within the app
  • I send a JWT to the API which is inspected and from which the Supabase Auth User ID value is extracted (this is the ‘sub’ in the JWT)
  • I give this user ID to Supabase via the .eq() method of the database call
  • RLS is active on the table

The issue is that this workflow works from one context but not another:

  • I can successfully use a PUT request to the API to update the profile from a HTTP client (I’m using Insomnia)
  • When I make this same API call from within the iOS app everything is apparently successful except the the database update is not committed.

I have tried disabling RLS but the update is again:

  1. successful from Insomnia
  2. failing from iOS
  • I use the same JWT in both contexts so rule out security failures with the API
  • Tokens are not expired
  • Keeping or removing RLS on the table has no effect
  • Reviewing logs doesn’t show anything abnormal
  • Reviewing header values, whilst different between the platforms, doesn’t indicate anything thats wrong

Given the platform I have described it’s difficult to share any code that might indicate where a problem lies. I in fact don’t think it’s my code… but there is nothing anywhere to suggest what is causing the update to fail.

A small block of code just to illustrate the failure point:

const response = await Client.connection
     .from(this.tableName)
     .update({
       "given_name": updateProfileDto.givenName,
       "family_name": updateProfileDto.familyName
     })
    .eq("user_id", this.session.getUser()) // <--- this is a UUID
    .select()
     
 return { message: "Updated", data: response.data }

The short of it is that the write of the update does not occur when triggered from the iOS context, but does when called from Insomnia.

If anyone has any thought on what I could investigate I’d love to hear from you!

:worried:

I finally got to the bottom of this, and of course the error was mine rather than any system failing or security mis-configuration…

There were in fact several issues:

1.) In Swift there is concept of ‘CodingKeys’ which is a way for Swift to understand how to encode and decode JSON data into appropriately typed objects, without telling Swift exactly what we are sending or expecting it doesn’t know what to do. Being new to swift I had implemented these keys against the payload object for the update request which turned (E.g) givenName into given_name.

2.) Being new to Nest I had extended a validation DTO from a base class (createUser) which did not do what I expected. Therefore in UpdateUser this effectively passed along undefined values to the updateUser() function.

3.) Having undefined values in the request data resulted in asking postgres to set the (e.g) givenName to undefined which it silently refused to do.

Only a series of logging uncovered this . The request travelling from the client iOS app all the way through to the database call to update() led down the path of assuming this was a permissions issue with the table because it all worked but never committed. There were no messages from Supabase to indicate what the problem was and I headed down the rabbit hole of Googling and ChatGPT to work out how to get to the bottom of it.