postgres_changes INSERT/UPDATE not delivered to client despite SUBSCRIBED channel and valid RLS #47579
-
|
Project ref: SymptomChannel subscribes successfully ( Confirmed by watching the raw WebSocket Messages panel live in DevTools while inserting a row from another tab: only heartbeats appear, no Reproduced in
All three show the identical symptom, ruling out browser profile, extensions, and local network as causes. Environment
Hypotheses tested and ruled out1. RLS blocking the row from its own owner — ✅ Ruled out 2. Multiple client instances / bundler chunk duplication of the singleton — ✅ Ruled out 3. Insert mechanism (Server Action / RPC vs raw insert) — ✅ Ruled out 4. 5. 6. Realtime concurrent connection quota — ✅ Ruled out 7. Stale/leaked WebSocket connections competing for the topic — What is confirmed working, every time, via direct script against the live project
Every mechanism reachable from a Node script, against the same live project, behaves correctly. The failure is only observed in the real browser bundle, across three independent browsers/devices/networks. What we're askingCould someone check server-side Realtime logs for connections from project
Reproduction timestamp(s)channel/topic: realtime:public:projects (or exact string from the phx_join payload) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
Check with a simulated user in the realtime tab of the dashboard. If that works then the issue is in your client code (maybe not setting the session in the client before it subscribes). The inspector runs in your browser so also eliminates network type issues. |
Beta Was this translation helpful? Give feedback.
-
|
Since Realtime enforces RLS on Things to check, in order:
In practice the vast majority of these reports come down to #1. Hope this helps! |
Beta Was this translation helpful? Give feedback.
-
|
Found the root cause, and it was suggested by @harrysun2006 above — thank you! The SELECT relreplident FROM pg_class WHERE relname = 'projects'; After running: ALTER TABLE public.projects REPLICA IDENTITY FULL; INSERT and UPDATE events started arriving correctly on the client with the full row payload. Everything else we tested (RLS policies, client singleton, @supabase/ssr vs vanilla client, hydration mismatches) was actually fine — REPLICA IDENTITY was the real blocker all along. For anyone hitting the same symptom (channel status SUBSCRIBED, heartbeat working, but postgres_changes events never arriving despite correct RLS and a healthy connection): check REPLICA IDENTITY on the table first. Also tried adding an explicit realtime.setAuth(token) call on every auth state change (including INITIAL_SESSION) as defense-in-depth, but couldn't find evidence it was necessary on its own with @supabase/supabase-js 2.106.0 once REPLICA IDENTITY was fixed. Thanks again for the help! |
Beta Was this translation helpful? Give feedback.
Since Realtime enforces RLS on
postgres_changes, the usual cause of "SUBSCRIBED + heartbeats fine but zero change events" is that the socket is connected anonymously — with@supabase/ssrthe browser client often doesn't have the user's access token attached, so RLS silently drops every event.Things to check, in order:
REPLICA IDENTITY FULLon the table (needed for UPDATE/DELETE payloads and for RLS to evaluate the row):