Demo, all content is generated
Question

Realtime DELETE payload only has the id, how do I know which list to remove it from?

Solved · 461 views · asked by lily_chen · edited

Kanban board. I subscribe to postgres_changes on cards. For INSERT and UPDATE I get the full row. For DELETE, payload.old is just:

{ "id": "4e1c..." }

I need column_id to know which column to remove it from. Cursor told me to run alter table cards replica identity full which I did, still only the id.

What I’ve tried

Ran the replica identity full, re-subscribed, restarted the dev server.

Comment

3 answers

Marked as helpful by the asker
jb_supa · edited

That's intended when the table has RLS. Realtime can't check RLS on a row that no longer exists, so for DELETE it only sends the primary key to avoid leaking deleted data to people who weren't allowed to see it. Replica identity full doesn't change that with RLS on.

You don't need the column id though. You already have all cards in state, so remove by id:

if (payload.eventType === 'DELETE') {
  setCards((cards) => cards.filter((c) => c.id !== payload.old.id))
}

If you keep cards grouped per column, keep a flat Map<id, card> next to it, or derive the columns from one flat list. Also worth knowing: DELETE events aren't filtered by RLS either, so every subscriber gets the ids of deleted cards. Ids only, but don't put anything meaningful in the id.

Comment
Switched to a flat list and derive the columns with useMemo. Simpler anyway. You can revert the replica identity I assume? lily_chen · edited
Yes, replica identity default. Full makes every update write more WAL, no point keeping it. jb_supa · edited
oksana_k · edited

Alternative: soft delete. Set archived_at instead of deleting, then it's an UPDATE and you get the full row. Useful anyway if people want undo on a board.

Comment
Undo is on the wishlist so maybe later, good idea. lily_chen · edited
tom_brewer · edited

What we did: broadcast from a trigger with realtime.broadcast_changes. You get the old row in the payload and you control who can listen via RLS on realtime.messages. More setup, but no more id-only deletes.

Comment
Good option, and the RLS on realtime.messages is the part people miss. Thanks for adding it. jb_supa · edited