supabase / realtime

Broadcast, Presence, and Postgres Changes via WebSockets
https://supabase.com/realtime
Apache License 2.0
6.7k stars 299 forks source link

Table INSERT subscriptions fail with Error 401: Not Unauthorized #1107

Open vyknight opened 1 year ago

vyknight commented 1 year ago

Describe the bug

I've subscribed to inserts on a table using the supabase api, when I add a row into that same table on the supabase web interface I receive notice that a change has occurred but not the content of the row that was inserted. I've ensured that the table has been added to the supabase-realtime channel just like the guide. I have tried to disable/enable RLS, giving all permissions to both anon and public roles, and also tried to use the api service key. None of these resolved the 401: unauthorized error.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

Code to subscribe to channel, which I copied from the API tab on the web interface.

const { createClient } = require('@supabase/supabase-js')

const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)

const coachMessages = supabase.channel('custom-insert-channel')
  .on(
    'postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'coach_messages' },
    (payload: any) => {
      console.log('Change received!', payload)
    }
  )
  .subscribe()

console.log(coachMessages)

and the error:

image

Row insertion and database actions are done using the supabase web interface.

Expected behavior

A clear and concise description of what you expected to happen.

The payload to contain the row that was just inserted in the payload.new property.

System information

iamgmd commented 1 year ago

I am experiencing the same problem in 2.33.2. Is there a fallback version I can use until this bug is fixed?

btw.. I am using @nuxtjs/supabase and therefore const supabase = useSupabaseClient(); to create the subscription. I assume that it is a wrapper around @supabase/supabase-js.

mfissehaye commented 1 year ago

I am having the same problem.

iamgmd commented 1 year ago

Ok, I think I got this to work but I am not sure as to why, maybe someone who is advanced in this topic maybe able to shed some light.

I turned off RLS for the table followed by:

grant select on table to anon;

as documented in Bring your own database

after I did that, I get the payload.

UPDATE: I needed both anon and authenticated for my shopping cart so:

grant select on transactions to anon, authenticated;

mfissehaye commented 1 year ago

Ok, I think I got this to work but I am not sure as to why, maybe someone who is advanced in this topic maybe able to shed some light.

I turned off RLS for the table followed by:

grant select on table to anon;

as documented in Bring your own database

after I did that, I get the payload.

UPDATE: I needed both anon and authenticated for my shopping cart so:

grant select on transactions to anon, authenticated;

That makes it work. Thank you.

vyknight commented 1 year ago

Ok, I think I got this to work but I am not sure as to why, maybe someone who is advanced in this topic maybe able to shed some light.

I turned off RLS for the table followed by:

grant select on table to anon;

as documented in Bring your own database

after I did that, I get the payload.

UPDATE: I needed both anon and authenticated for my shopping cart so:

grant select on transactions to anon, authenticated;

This worked for me as well, thank a lot.

johnsutor commented 11 months ago

Make sure you have the Authorization header set on the webhook as well, as that can cause a 401

peterj commented 9 months ago

The "Missing grants" section in the troubleshooting docs helper me fix this issue: https://supabase.com/partners/integrations/prisma#troubleshooting

yellow-mi commented 4 months ago

I get an error when I try to set anon for my table, any other workaround?

HStromfelt commented 3 months ago

I am hitting this problem as well.

I am watching for UPDATEs like so:

...
.on(
  "postgres_changes", { schema: "public", table: "Feed", event: "UPDATE" },
  (payload) => console.log("UPDATE", payload)
)
.subscribe()

All of my requests are via an authenticated client, so I only worry about the authenticated role.

I am finding that if I do not run grant select on "public"."Feed" to authenticated; then I get the 401 error, regardless of whether RLS is enabled for the given table.

If I run the grant command, then if RLS is enabled, the events don't fire -> now nothing gets console logged. If I remove RLS, then the events fire properly, without the 401 error.

I am not sure why RLS would block the event like that - my only guess would be that the RLS is too restrictive, but this is my RLS policy:

create policy "policy_name"
on "public"."Feed"
as PERMISSIVE
for ALL
to authenticated
using (
  true
);

so I am being as insecure as possible with my RLS policy.

pablojsx commented 3 months ago

Same:

image

yethuhlaing commented 1 month ago

Ok, I think I got this to work but I am not sure as to why, maybe someone who is advanced in this topic maybe able to shed some light.

I turned off RLS for the table followed by:

grant select on table to anon;

as documented in Bring your own database

after I did that, I get the payload.

UPDATE: I needed both anon and authenticated for my shopping cart so:

grant select on transactions to anon, authenticated;

Thanks! That solves the problem.