Jeremie Bruzzi
 · Lead Project Manager

Custom Action : Supabase Realtime Presence

Hello,

Just to share with the community how to implement an online user functionality using supabase.

  1. Create an App State onlineUsers

    You need to define an application state to store the online user IDs. This can be done using a state management Aka App State

  2. Create a Custom Action onlineUsers

    Define a custom action that listens to and updates the onlineUsers app state. This action should be responsible for updating the list of online user IDs in response to events or changes in the Presence channel

  3. Add an action On Page Load

    To populate the onlineUsers app state with the initial online user IDs, you can create an action that runs when the page loads, using the authenticated user's ID as an input argument.

  4. Using the onlineUsers State

    With the onlineUsers app state now populated with online user IDs, you can use it in your Flutter application as needed. For example, you can use conditional visibility to display specific UI elements based on whether a user is online.
    Since i'm a huge fan of ConditionalBuilder Widget a quick exemple

    By following these steps, you can create a dynamic and real-time online user functionality in your FlutterFlow application using Supabase. It's a flexible approach that allows you to customize the user experience based on the online status of users.


    Now the fun is yours, you have a real time list of online user at the App Level to play with.


    Yep, Yep if only App State could have a Supabase Row Type for list... and / or a return type of Stream instead of Future for Action... life would be wonderfull.

    Code for custom action :

import 'package:supabase_flutter/supabase_flutter.dart';

Future onlineUsers(BuildContext context, String userID) async {
  // Add your function code here!
  final channel = Supabase.instance.client
      .channel('Online', opts: RealtimeChannelConfig(self: true));
  channel.on(RealtimeListenTypes.presence, ChannelFilter(event: 'sync'),
      (payload, [ref]) {
    // Update the lobby count
    final presenceState = channel.presenceState();
    FFAppState().onlineUsers = presenceState.values
        .map((presences) =>
            (presences.first as Presence).payload['user_id'] as String)
        .toSet().toList();
  }).subscribe(
    (status, [ref]) async {
      if (status == 'SUBSCRIBED') {
        await channel.track({'user_id': userID});
      }
    },
  );
}


12
5 replies