supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
746 stars 184 forks source link

inFilter method in streams doesn't filter table if it is primary key #852

Open Lazizbek97 opened 8 months ago

Lazizbek97 commented 8 months ago

Describe the bug I have one table(chats) which has id auto generated when any items added. other table(chat_members) connected with this table's id field(foreign key pairs). when i listen this chats table, with following code:

final currentUserId = supabase.auth.currentUser?.id;

    final memberSubquery = await supabase
        .from('chat_members')
        .select('chat_id')
        .eq('user_id', currentUserId ?? '');

final List<dynamic> currentUserChatIds =
        memberSubquery.map((e) => e.values.firstOrNull ?? '').toList() ?? [];

  final messageStream = supabase
          .from('chats')
          .stream(primaryKey: ['id']).inFilter('id', chatIds as List<String>);

 await emit.forEach(messageStream, onData: (data) {
        final chats = data.map((e) => ChatMd.fromMap(e)).toList();
        return ChatsLoaded(chats);
      });

it is not giving chats, where its id contains currentUserChatIds.

Expected behavior i want to filter chats where its id are in current user's chats id list.

Screenshots Here is chat table

Screenshot 2024-03-09 at 13 48 50

Here is chat member table, where members added when user click on join button

Screenshot 2024-03-09 at 13 49 16

Additional context flutter version:


Framework • revision 41456452f2 (6 weeks ago) • 2024-01-25 10:06:23 -0800
Engine • revision f40e976bed
Tools • Dart 3.2.6 • DevTools 2.28.5```

supabase version:
supabase_flutter: ^2.3.4
dshukertjr commented 8 months ago

In your code, where does chatIds come from? Was it a typo and chatIds is meant to be currentUserChatIds?

Could you confirm if the filter is not working when you use a hardcoded value like the following?

final messageStream = supabase
          .from('chats')
          .stream(primaryKey: ['id']).inFilter('id', ['hard-coded-uuid-value-from-chats']);
Dario-Ciceri commented 4 months ago

In your code, where does chatIds come from? Was it a typo and chatIds is meant to be currentUserChatIds?

Could you confirm if the filter is not working when you use a hardcoded value like the following?

final messageStream = supabase
          .from('chats')
          .stream(primaryKey: ['id']).inFilter('id', ['hard-coded-uuid-value-from-chats']);

Hi, I have the same issue with RealtimeChannel:

RealtimeChannel realtimeChannel = _db
        .channel('ingredients') 
        .onPostgresChanges(
          event: PostgresChangeEvent.delete,
          schema: 'public',
          table: 'ingredients,
          filter: PostgresChangeFilter(
            type: PostgresChangeFilterType.inFilter,
            column: 'id',
            value: [1,5,7],
          ),
          callback: (payload) => log('deleted $payload'),
        )
        .subscribe();

id is int8, primary key and identity. it seems as if the filter is not being applied since it doesn't matter what I delete, I can even delete something with ID 1000 but I still get notified of the deletion, when I was only interested in those in the filter! How do I verify the name of the realtimechannel? thanks.

update: with .stream(primaryKey: ['id']).inFilter('id', ids) it works... but I need to listen for PostgresChangeEvent.delete only

dshukertjr commented 4 months ago

@Dario-Ciceri That is a known limitation of Supabase realtime. https://github.com/supabase/realtime/issues/585

fjnoyp commented 4 months ago

Should you guys update your docs then? The only inFilter example is with the primary id:

https://supabase.com/docs/reference/dart/stream

dshukertjr commented 4 months ago

@fjnoyp inFilter on primary keys does work as expected. In my previous comment, I was talking about this behavior being a known behavior, which is documented here.