Realtime only getting DELETE events
I've found many cases of this happening to others, but in all cases, as far as I can tell, it's been because the user is doing something unusual/custom.
In my case I have a very simple setup. Just a single "shopping" table in my public schema. The only thing I can think that might be wrong is the RLS policy I set on the table.
Since I wanted only authenticated users to use my app, but all authenticated users should have access to everything in the "shopping" table, I made a policy like this:

18 Replies
You probably are not authenticated then.
Try to anon.
Delete ignores the RLS policy.
I am quite sure I'm authenticated. I am able to use the supabase-js client to do inserts/updates/deletes, And I also make sure not to subscribe until I have authenticated.
Realtime only looks at the select policy.
Ah
Try TO anon and see if it works.
Can you explain what you mean by "try to anon"? Do you mean try subscribing without being authenticated, in my client code?
Change the policy you show so that it is TO anon and not To authenticated as a test.
You may not have a user session when you set up the realtime connection.
I see - I'll try that!
This is just a debug step.
I have code to make sure to wait to start the subscription until after a getSession is successful. So it should be fined
You also can use the realtime monitor in the dashboard with user impersonation to rule out RLS versus your code.
Well, realtime is working as you get deletes and they don't have to meet RLS so it seems you don't meet RLS and your policy is very simple.
Ok so I changed the policy to be anon instead of authenticated.
Then I ran this in a plain node-script (separate from my client app)
And I tried inserting an item via the table-editor in my supabase-project
And the event came through!
So I guess either there is something wrong with the way I had my authenticated policy set up, or, like you said, I am, perhaps, subscribing before I am authorized (despite my best efforts to ensure I don't).
The latter I can debug. But as to the former: should I make a separate policy for SELECT to make sure realtime works?
I never use ALL as it is confusing if you do add another policy. Much clearer to specify each. BUT if you only have ALL then authenticated user should have worked with policy you had. You can use the realtime monitor to check that as you can impersonate a user there.
Also note if you are doing a new app it is recommended to use Broadcast changes or DB messaging now with private channels than postgres_changes. It is more complex but runs alot faster and much less load on DB so can support more users.
I tried the realtime monitor now (didn't know it existed - pretty cool!) after reinstating the "authenticated" RLS policy (for all).
In there I impersonate an authenticated user, and I can see all events, inserts, updates as well as deletes.
But in my client I'm still only getting deletes.
I suppose that means that I am subscribing wrong, somehow. That maybe I am not authenticated after all when I'm subscribing. Does that sound like a correct analysis?
Thanks btw for the tip to look into private channels. Will check it out later. My needs arent huge at the moment though as this is just a simple learner-project.
Everything points to not having a user session when you subscribe.
You should be able to log out getSession right before the subscription
Alright thanks so much for your help! I will have to continue debugging this a bit later. But now I have a lot more to go on. Appreciate it!
After a ton of in debugging help from ChatGPT, I finally cracked this one. (ChatGPT5 is crazy smart btw).
Here is the script I was running before to test realtime database changes (minus the secret constants of course) - I was getting DELETE events but not INSERT or UPDATE:
ChatGPT helped me eventually zone in on this script which works perfectly:
The key difference here is the addition of:
It seems that even though I was being very careful not to start my subscription until after authenticating (and making sure I had a session), the realtime engine in supabase didn't know about it! I have to manually tell it my access token!
This should really be documented somewhere. If it already is I haven't spotted it.
It should not be required to do setAuth for normal supabase-js stuff. That is normally used for custom JWTs. I've never used it.
I suspect maybe there is something about the fact I was prototyping this on node and not a browser. Now that I know it works I can build it in to my app for the browser, and maybe the realtime.setAuth won’t be necessary there