Files

2.1 KiB

Realtime Backend Configuration

Use migrations to create realtime channel patterns, publish database changes, and restrict channel access before wiring frontend subscriptions.

Create Channel Patterns

INSERT INTO realtime.channels (pattern, description, enabled)
VALUES ('order:%', 'Per-order updates', true)
ON CONFLICT (pattern) DO UPDATE
SET description = EXCLUDED.description,
    enabled = EXCLUDED.enabled;

Publish From App-Owned Tables

Attach triggers to app-owned tables, then call realtime.publish(...) from the trigger function.

CREATE OR REPLACE FUNCTION public.notify_order_status()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM realtime.publish(
    'order:' || NEW.id::text,
    'status_changed',
    jsonb_build_object('id', NEW.id, 'status', NEW.status)
  );

  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER order_status_trigger
AFTER UPDATE ON public.orders
FOR EACH ROW
WHEN (OLD.status IS DISTINCT FROM NEW.status)
EXECUTE FUNCTION public.notify_order_status();

Restrict Channel Access

realtime.channels and realtime.messages can be managed with RLS. Put those policies in migrations.

Restrict who can subscribe to order channels:

ALTER TABLE realtime.channels ENABLE ROW LEVEL SECURITY;

CREATE POLICY users_subscribe_own_orders
ON realtime.channels FOR SELECT
TO authenticated
USING (
  pattern = 'order:%'
  AND EXISTS (
    SELECT 1 FROM public.orders
    WHERE id = NULLIF(split_part(realtime.channel_name(), ':', 2), '')::uuid
      AND user_id = (SELECT auth.uid())
  )
);

Restrict who can publish chat messages:

ALTER TABLE realtime.messages ENABLE ROW LEVEL SECURITY;

CREATE POLICY members_publish_chat
ON realtime.messages FOR INSERT
TO authenticated
WITH CHECK (
  channel_name LIKE 'chat:%'
  AND EXISTS (
    SELECT 1 FROM public.chat_members
    WHERE room_id = NULLIF(split_part(channel_name, ':', 2), '')::uuid
      AND user_id = (SELECT auth.uid())
  )
);

Do not attach developer triggers to realtime.channels or realtime.messages; publish from triggers on public tables.