supabase-flutter icon indicating copy to clipboard operation
supabase-flutter copied to clipboard

Inconsistent behavior when streaming table on document insert

Open michaeljajou opened this issue 11 months ago • 2 comments

Describe the bug Inconsistent behavior when streaming a table for an entry that has not been inserted yet. Upon a user authenticating, I have an edge function that creates a user object the database. In my client app, I have a stream on the users table for this newly authenticated user. About 98% of the time this works, but there is a rare case where the stream never notifies the listener that a new object has been created. No errors are logged from Supabase whatsoever.

Expected behavior A clear and concise description of what you expected to happen. When an object is inserted into the table I am streaming, I should be notified every time or an error should be thrown.

Version (please complete the following information): ├── supabase_flutter 2.8.2 │ ├── supabase 2.6.1 │ │ ├── functions_client 2.4.0 │ │ ├── gotrue 2.11.1 │ │ ├── postgrest 2.4.0 │ │ ├── realtime_client 2.4.1 │ │ ├── storage_client 2.3.0

Additional context

// Auth state change is streamed, which executes successfully every time
    return client.auth.onAuthStateChange.map((e) {
      switch (e.event) {
        case AuthChangeEvent.signedOut:
          return null;
        default:
          if (e.session?.user.id != null) {
            _observeUser(e.session!.user.id);
          }
      }
    });
    
    // UserService
      @override
      Stream<User?> listen(String uid) {
        return client
            .from('users')
            .stream(primaryKey: ['id'])
            .eq('id', uid)
            .map((event) => event.isNotEmpty ? User.fromJson(event.first) : null);
      }

   // Bloc Class
   void _observeUser(String uid) {
         _userListener = ApiUser.instance.listen().listen((uid) async {
        if (user == null) {
          log('User not found yet', name: 'AuthCubit');
          return;
        }
        log(user.id, name: 'AuthCubit');
   }

98% Of The Time [AuthCubit] User not found yet [AuthCubit] "USER_ID"

2% Of The Time [AuthCubit] User not found yet ---- Nothing gets logged again -----

michaeljajou avatar Dec 18 '24 18:12 michaeljajou

How exactly is your edge function called? I guess it's a trigger, but could you show the code for that?

Vinzent03 avatar Dec 18 '24 22:12 Vinzent03

Deno.serve(async (req) => {
  try {
    const payload: InsertPayload = await req.json();
    const authUser = payload.record;
    const supabaseClient = createClient(
      Deno.env.get("URL") ?? "",
      Deno.env.get("KEY") ?? "",
    );
    const user: User = {
      id: authUser.id,
      email: authUser.email,
      created_at: authUser.created_at,
    };
    const { error } = await supabaseClient
      .from("users")
      .insert(user);
    if (error) throw error;
    return ResponseType.success("User created successfully");
  } catch (error) {
    console.error("Error creating user", error);
    return ResponseType.error(error);
  }
});

Trigger succeeds every time. It is setup as a webhook to run on auth_users.insert

michaeljajou avatar Dec 18 '24 22:12 michaeljajou