gotchatypescriptModerate
Supabase Realtime Channel Requires Explicit Subscribe Call to Receive Events
Viewed 0 times
supabaserealtimesubscribepostgres changeschannelRLSwebsocket
Error Messages
Problem
Supabase Realtime channel is created and event handlers are registered with .on() but no events arrive. The code looks correct but the subscription never activates.
Solution
A Supabase Realtime channel does not start receiving events until .subscribe() is called. The callback passed to subscribe fires when the subscription is confirmed by the server.
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
const channel = supabase
.channel('table-changes')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'messages' },
(payload) => {
console.log('Change received:', payload);
}
)
.subscribe((status) => {
if (status === 'SUBSCRIBED') {
console.log('Realtime subscription active');
}
}); // <-- this call is mandatory
// Cleanup
return () => { supabase.removeChannel(channel); };Why
Supabase Realtime uses a lazy activation model — channels are registered locally but the server-side subscription is only established when subscribe() is called. This allows batching multiple .on() handlers before connecting.
Gotchas
- Call supabase.removeChannel(channel) in useEffect cleanup to prevent memory leaks and duplicate subscriptions.
- Supabase Realtime requires Row Level Security to be enabled on the table you are subscribing to.
- The 'CHANNEL_ERROR' status in the subscribe callback usually means RLS is blocking the subscription.
- Broadcast and Presence are separate channel types — don't mix postgres_changes with broadcast on the same channel.
Revisions (0)
No revisions yet.