Files
supabase/apps/docs/pages/guides/realtime/postgres-changes.mdx
T
dngandWen Bo Xie dbcafd687e Postgres CDC -> Postgres Changes (#10649)
* Postgres CDC -> Postgres Changes

* Fix typo

* docs: update Realtime description from CDC to Changes

Co-authored-by: Wen Bo Xie <wenbo.xie3@gmail.com>
2022-12-01 11:31:59 -08:00

124 lines
4.0 KiB
Plaintext

import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'postgres-changes',
title: 'Postgres Changes',
description: "Getting started with Realtime's Postgres Changes feature",
}
Realtime's Postgres Changes feature listens for database changes and sends them to clients. Clients are required to subscribe with a JWT dictating which changes they are allowed to receive based on the database's [Row Level Security](/docs/guides/auth/row-level-security).
Anyone with access to a valid JWT signed with the project's JWT secret is able to listen to your database's changes, unless tables have [Row Level Security](/docs/guides/auth/row-level-security) enabled and policies in place.
Clients can choose to receive `INSERT`, `UPDATE`, `DELETE`, or `*` (all) changes for all changes in a schema, a table in a schema, or a column's value in a table. Your clients should only listen to tables in the `public` schema and you must first enable the tables you want your clients to listen to.
Postgres Changes works out of the box for tables in the `public` schema. You can listen to tables in your private schemas by granting table `SELECT` permissions to the database role found in your access token. You can run a query similar to the following:
```sql
GRANT SELECT ON "private_schema"."table" TO authenticated;
```
<Admonition type="caution">
We strongly encourage you to enable RLS and create policies for tables in private schemas. Otherwise, any role you grant access to will have unfettered read access to the table.
</Admonition>
You can do this in the [Replication](https://app.supabase.com/project/_/database/replication) section in the Dashboard or with the [SQL editor](https://app.supabase.com/project/_/sql):
```sql
begin;
-- remove the supabase_realtime publication
drop publication if exists supabase_realtime;
-- re-create the supabase_realtime publication with no tables
create publication supabase_realtime;
commit;
-- add a table to the publication
alter publication supabase_realtime add table messages;
```
By default, only `new` record changes are sent but if you want to receive the `old` record (previous values) whenever you `UPDATE` or `DELETE` a record,
you can set the `replica identity` of your table to `full`:
```sql
alter table messages replica identity full;
```
To listen to all changes in the `public` schema:
```js
const { createClient } = require('@supabase/supabase-js')
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)
/*
Channel name can be any string.
Event name can can be one of:
- INSERT
- UPDATE
- DELETE
- *
*/
const channel = supabase
.channel('schema-db-changes')
.on('postgres_changes', { event: '*', schema: 'public' }, (payload) => console.log(payload))
.subscribe()
```
To listen to changes on a table in the `public` schema:
```js
// Supabase client setup
const channel = supabase
.channel('table-db-changes')
.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) =>
console.log(payload)
)
.subscribe()
```
To listen to changes when a column's value in a table matches a client-specified value:
```js
// Supabase client setup
const channel = supabase
.channel('value-db-changes')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'messages',
filter: 'body=eq.hey',
},
(payload) => console.log(payload)
)
.subscribe()
```
To listen to different events and schema/tables/filters combinations with the same channel:
```js
// Supabase client setup
const channel = supabase
.channel('db-changes')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'messages', filter: 'body=eq.bye' },
(payload) => console.log(payload)
)
.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'users' }, (payload) =>
console.log(payload)
)
.subscribe()
```
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page