How it works
A channel is a name, likeroom:design. Everyone subscribed receives what’s sent to it. A channel rule matches a pattern of names (room:*) and decides who may join and send, whether presence is tracked, and how many messages are kept for latecomers.
Channel history is a backlog for context. With the rule’s Kind set to Durable, kept messages also survive a restart, for the rule’s Retention. It still isn’t a searchable archive. If messages must be kept forever (searchable, exportable), also save them to a table; see Variation: permanent messages.
1. Create the channel rule
Realtime → Channels → New channel rule:2. Open a room
src/room.ts
3. Send messages
{ id, channel, event, payload, from, sent_at }. from is the sender’s user id (or "server" for your backend), filled in by Pawabase, so it can’t be faked. Show payload.name, but trust from.
4. Who’s online
members, with different presence_refs; group by user_id. Entries disappear when someone leaves or their connection drops.
5. Typing indicators
Typing is frequent and disposable, so send it as a message instead of presence, and don’t keep it:6. Make rooms private to their members
Keep aroom_members table (room_id, user_id) and check membership in the rule. Channel rules read the caller and the channel name, not other tables, so give each member the channel through their token, or put the members in the channel’s name. The simplest secure pattern uses the person’s id in the channel name for direct messages, and an organization for team rooms:
A placeholder like
{{ auth.org }} counts as a wildcard when deciding which rule governs a channel, and must equal the caller’s own value to let them in: someone at Globex asking for org:acme:room:design is governed by this rule and refused, rather than falling through to a looser default. See Channel rules and Rules on realtime.
For rooms whose members are a list you manage yourself, publish messages from a flow that checks membership, and let clients only subscribe.
Variation: permanent messages
To keep every message, write it to amessages table, and let the table broadcast it:
- Create
messages(room_id,author_idas Owner field,text) with suitable rules. - Turn on Broadcast changes in the table’s settings.
- Send with
pawabase.from("messages").create({ room_id, text }), and listen with record changes.
Test it
Open two browsers signed in as different people, join the same room, and check: messages appear in both, the online list shows both, typing shows on the other side, and reloading shows the last messages. In Activity → Realtime, watch policy errors while you try a room you shouldn’t reach.Troubleshooting
Channels
The full channel API.
Channel rules
Patterns, kinds and limits.