Subscribing to Database Changes
Listen to database changes in real-time from your website or application.
You can use Supabase to subscribe to real-time database changes. There are two options available:
- Broadcast. This is the recommended method for scalability and security.
- Postgres Changes. This is a simpler method. It requires less setup, but does not scale as well as Broadcast.
Using Broadcast
To automatically send messages when a record is created, updated, or deleted, we can attach a Postgres trigger to any table. Supabase Realtime provides a realtime.broadcast_changes()
function which we can use in conjunction with a trigger.
Broadcast authorization
Realtime Authorization is required for receiving Broadcast messages. This is an example of a policy that allows authenticated users to listen to messages from topics:
12345create policy "Authenticated users can receive broadcasts"on "realtime"."messages"for selectto authenticatedusing ( true );
Create a trigger function
Let's create a function that we can call any time a record is created, updated, or deleted. This function will make use of some of Postgres's native trigger variables. For this example, we want to have a topic with the name topic:<record id>
to which we're going to broadcast events.
1234567891011121314151617create or replace function public.your_table_changes()returns triggerlanguage plpgsqlas $$begin perform realtime.broadcast_changes( 'topic:' || coalesce(NEW.topic, OLD.topic) ::text, -- topic - the topic to which we're broadcasting TG_OP, -- event - the event that triggered the function TG_OP, -- operation - the operation that triggered the function TG_TABLE_NAME, -- table - the table that caused the trigger TG_TABLE_SCHEMA, -- schema - the schema of the table that caused the trigger NEW, -- new record - the record after the change OLD -- old record - the record before the change ); return null;end;$$;
Create a trigger
Let's set up a trigger so the function is executed after any changes to the table.
12345create trigger handle_your_table_changesafter insert or update or deleteon public.your_tablefor each rowexecute function your_table_changes ();
Listening on client side
Finally, on the client side, listen to the topic topic:<record_id>
to receive the events. Remember to set the channel as a private channel, since realtime.broadcast_changes
uses Realtime Authorization.
12345678910const gameId = 'id'await supabase.realtime.setAuth() // Needed for Realtime Authorizationconst changes = supabase .channel(`topic:${gameId}`, { config: { private: true }, }) .on('broadcast', { event: 'INSERT' }, (payload) => console.log(payload)) .on('broadcast', { event: 'UPDATE' }, (payload) => console.log(payload)) .on('broadcast', { event: 'DELETE' }, (payload) => console.log(payload)) .subscribe()
Using Postgres Changes
Postgres Changes are simple to use, but have some limitations as your application scales. We recommend using Broadcast for most use cases.
Enable Postgres Changes
You'll first need to create a supabase_realtime
publication and add your tables (that you want to subscribe to) to the publication:
123456789101112131415begin;-- remove the supabase_realtime publicationdrop publication if exists supabase_realtime;-- re-create the supabase_realtime publication with no tablescreate publication supabase_realtime;commit;-- add a table called 'messages' to the publication-- (update this to match your tables)alter publication supabase_realtime add table messages;
Streaming inserts
You can use the INSERT
event to stream all new rows.
123456789101112131415import { createClient } from '@supabase/supabase-js'const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)const channel = supabase .channel('schema-db-changes') .on( 'postgres_changes', { event: 'INSERT', schema: 'public', }, (payload) => console.log(payload) ) .subscribe()
Streaming updates
You can use the UPDATE
event to stream all updated rows.
123456789101112131415import { createClient } from '@supabase/supabase-js'const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)const channel = supabase .channel('schema-db-changes') .on( 'postgres_changes', { event: 'UPDATE', schema: 'public', }, (payload) => console.log(payload) ) .subscribe()