In modern applications, understanding user presence – knowing who is online and active – is crucial for features like chat indicators, live collaboration, and even showing user activity. Supabase's Realtime subscriptions offer a powerful and straightforward way to implement presence tracking.
The core idea behind Supabase presence is to leverage the realtime connection. When a user connects to Supabase's realtime, they are considered 'present'. When they disconnect, they are no longer present. Supabase provides built-in events and an API to manage and subscribe to these presence changes.
Let's break down how to implement this:
-
Setting up a Presence Channel:
To track presence, you'll typically subscribe to a specific channel. This channel acts as a broadcast for presence events related to a particular context, like a specific chat room or a document.
const channel = supabase.channel('presence_channel', {
config: {
presence: {
key: 'user_id'
}
}
});In this code, presence_channel is the name of our channel. The presence: { key: 'user_id' } configuration is vital. It tells Supabase how to uniquely identify each presence entry. In most cases, this will be a user ID.
-
Subscribing to Presence Events:
Once the channel is set up, you can subscribe to various presence-related events:
'presence': This event fires whenever the presence status of any user in the channel changes (someone joins or leaves).'sync': This event fires when the initial list of currently present users is sent after joining the channel.'join': This event fires specifically when a new user joins the channel.'leave': This event fires when a user leaves the channel.
channel.on('presence', {
event: 'join' // or 'leave', 'sync', 'presence'
}, ({ key, newState, leftPresences }) => {
console.log('Presence event:', key, newState, leftPresences);
});
channel.subscribe((status) => {
if (status === 'SUBSCRIBED') {
channel.track({ online_at: new Date().toISOString() });
}
});The channel.track() method is used to broadcast your own presence. Here, we're sending an object that includes the current timestamp. This data is associated with your unique key (the user ID) and can be accessed by other clients. The newState in the event payload contains the presence data for the user who triggered the event, and leftPresences lists users who have left.
-
Managing Presence Data:
The data you
trackis an object. This object can contain any relevant information about the user's presence. For instance, you could track their current status (e.g., 'away', 'busy'), the document they're editing, or their last active time.
channel.track({
user_id: 'your-current-user-id',
username: 'Alice',
status: 'online',
last_seen: new Date().toISOString()
});When another client receives a presence event, they can access this tracked data to update their UI. For example, you can iterate through the sync or presence events to display a list of online users and their associated data.
-
Visualizing Presence (Client-Side Logic):
The actual display of presence information happens on your frontend. You'll typically maintain a local state (an array or object) that stores the presence information for all users in the channel. When a
joinorleaveevent occurs, you update this state. Thesyncevent is useful for populating the initial list of online users when your application loads.
- Best Practices:
- Unsubscribe on Component Unmount: Always remember to unsubscribe from channels when the component that subscribed to them is no longer active. This prevents memory leaks and unnecessary network traffic.
- Keep Tracked Data Lean: Avoid sending excessively large objects in your
trackdata. Focus on the essential information needed for presence. - Robust Disconnection Handling: Supabase handles automatic disconnections and presence updates for you. However, on the client-side, you might want to implement some logic for when a user is considered 'idle' after a certain period of inactivity, even if the connection is technically still open.
graph TD
A[Client Connects] --> B{Supabase Realtime Server}
B --> C[Channel Joins]
C --> D[Presence Tracked]
D --> E{Presence Event Broadcast}
E --> F[Other Clients Receive Event]
F --> G[Update UI (e.g., online list)]
A --> H[Client Disconnects]
H --> I[Supabase Detects Disconnection]
I --> J[Presence Leave Event]
J --> E