supabase / realtime-js

An isomorphic Javascript client for Supabase Realtime server.
https://supabase.com
MIT License
321 stars 57 forks source link

Subscribe to Views / Multiple Rows / Multiple Columns #185

Open jdgamble555 opened 2 years ago

jdgamble555 commented 2 years ago

Feature request

I would like to subscribe to a query itself, not a table. I don't need multiple subscriptions, just one for the query. If the query changes (not always important if INSERT, UPDATE, or DELETE), I would like my observable to get updated.

Currently, we can only use this complicated subscribe version of this query:

Promise

this.supabase.from(col).select('*').eq(field, value).single()

Subscription

this.supabase.from(${col}:${field}=eq.${value}).on('*', (payload) => {})

Is your feature request related to a problem? Please describe.

Describe the solution you'd like

this.supabase.from(col).select('*').eq(field, value).single()
  .subscribe((snap) => {
    if (snap.type === 'added') {
     console.log(snap.data);
    }
  });

V2 is Getting MORE Complicated, and LESS Intuitive

https://supabase.com/blog/supabase-js-v2

supabaseClient
  .channel('any_string_you_want')
  .on(
    'postgres_changes',
    {
      event: 'INSERT',
      schema: 'public',
      table: 'movies',
    },
    (payload) => {
      console.log(payload)
    }
  )
  .subscribe()

While the multiplayer mode looks cool, let's complete the actual limitations of the current realtime data before moving on to more features!

Describe alternatives you've considered

I don't think there should be an alternative. In order for it to be easy, it should work just like the regular queries, but with a subscription.

All of these Database work the exact same way in Query mode as Subscription mode, and allow complex queries (as far as the database itself can handle):

Additional context

Related: https://github.com/supabase/realtime/issues/271 https://github.com/supabase/realtime-js/issues/97 https://github.com/supabase/supabase/discussions/1206 https://github.com/supabase/realtime/issues/222 https://github.com/supabase/supabase/discussions/3193 https://github.com/supabase/supabase/discussions/3748 https://github.com/supabase/supabase/discussions/5684 https://github.com/supabase/supabase/discussions/7735

w3b6x9 commented 2 years ago

@jdgamble555

Channel names could be automatic (perhaps with UUID in the background) if we don't want to select a channel.

Yes, we can generate a unique string on the client's behalf if one is not provided.

These classes and methods are MORE confusing, and don't help basic use cases.

Would love to hear more about this one. What do you mean by these classes and methods? How does it not support basic use cases?

We have discussed queries/views/graphql subscriptions internally and we'll explore it further before we prioritize it. I'll post updates here as we continue to discuss internally.

jdgamble555 commented 2 years ago

Would love to hear more about this one. What do you mean by these classes and methods? How does it not support basic use cases?

The .on and .channel with the complex parameters where there is no documentation about options.


What seems easier to understand:

1

supabaseClient
  .channel('any_string_you_want')
  .on(
    'postgres_changes',
    {
      event: 'INSERT',
      schema: 'public',
      table: 'movies',
    },
    (payload) => {
      console.log(payload)
    }
  )
  .subscribe()

2

const mySubscription = supabase
  .from('*')
  .on('*', payload => {
    console.log('Change received!', payload)
  })
  .subscribe()

I understand the broadcasting feature seems pretty cool to have. However, you have over complicated the subscription process for people who just want to subscribe to the database. I don't know that the broadcasting feature is really important or useful to most people when you could just store items in the database directly and subscribe to that. Perhaps a good compromise would be to add another method that emulates the promise method for postgres. This perhaps would call the unintuitive method # 1 that you have created for supabase-js-v2.

In most cases, I don't need to think about a public schema, I don't need to think about a channel name, and I don't need to think about an event. I want to subscribe to:

  1. All changes
  2. The public schema
  3. In postgres
  4. And I don't want to name a channel

The broadcasting feature is pretty cool, but we still don't have the NEEDED features with postgres subscriptions.

  1. There is a delay now in subscriptions !!! This should be fixed ASAP!
  2. We cannot filter any of our subscriptions except for a simple eq filter? Firebase straight up can do more than this. A lot of your clients are moving from Firebase for the relational data support, and you can't do relational data with real time subscriptions? a. Who decided to add the eq clause as a random string in a filter filter: 'body=eq.hey'? Why? Why would you do that, especially when you just wrote a new sdk version... b. Subscriptions should not work differently than postgres promises. In fact, I suggest you separate the broadcasting from the postgres subscriptions all together, as they are two different things. This would also solve # 1. But more importantly, let's add all the filters that promises have shall we!
  3. Besides a real hack of using RLS policies in certain circumstances, there is no real way to work around not being able to subscribe to your actual query. I don't want to subscribe to all my data. I only want to subscribe to my query. I don't need all inserts where x = y. I need a subset of those inserts, or any changes for that matter. There is no work around for that, and you guys are still talking about why subscribing to view changes are appropriate? This is HUGE!

Yes, web sockets in Supabase for the moment are very very limiting, and you guys don't seem to have the fixes on your roadmap just yet.

Let's change that please.

J

jfreyberg commented 1 year ago

Are there any updates regarding these issues? @jdgamble555 made some very valid points. The realtime feature needs filtering in order to make sense for most real-world use cases. I find it confusing and somewhat concerning that this is not a top priority, as it clearly should be, while other, much less relevant features are pushed forward.

jdgamble555 commented 1 year ago

It looks like they may have added the main six: eq, neq, gt, gte, lt, lte. Unfortunately there is no or filter yet, and you are limited to only one filter.

I have added it to my j-supabase package, although I admit, I have not tested this yet.

But again, we need ALL filters that are available on JS sdk, and the ability to use more than one. I am taking this as HOPE that this is becoming a priority, as it should.

J

jfreyberg commented 1 year ago

That surely is a step in the right direction. However without and and or functionality filtering is not viable for most use cases.

@w3b6x9 (or any other maintainer) could you please give an update on the status of this feature?

w3b6x9 commented 1 year ago

@jdgamble555 this is good feedback here: https://github.com/supabase/realtime-js/issues/185#issuecomment-1258851450. Will look it over and pass it on to the rest of the team. Also, what do you mean by postgres promises? Like the ability to perform db operations via PostgREST and get back a response on promise resolve in JS?

It looks like they may have added the main six: eq, neq, gt, gte, lt, lte

Yes, these filters are available.

We plan to integrate this Rust worker that improves the performance of filters and will revisit adding additional filters, and/or, etc.

jdgamble555 commented 1 year ago

Yes, I was referring to PostGRest. I honestly think the subscription version should be the exact duplicate of the query version (promise, postgrest, whatever you want to call it). I realize this is not completely doable, considering PostgRest has a long history. That being said, you don't have to reinvent or rethink conceptual ideas, you would just have to program them.

The reality is, when you need to watch changes in multiple records or queries, you need a way to filter them. One filter is simply not enough, as it would not be in any database.

We need to filter subscriptions the same way we need to filter normal queries. (minus ordering)

The order of importance in my opinion, is the following:

It would be nice to see any filter PostgRest can do, you could pass it to the realtime algorithm and use that. Perhaps the generated SQL could be passed to the realtime under-the-hood somehow? I would think this would be possible considering the RLS could accept nearly any types of filters.

Another option to consider in order to get complex realtime filtering, is to make GraphQL Subscriptions, and use the filters in GraphQL.

J

sampl commented 1 year ago

I honestly think the subscription version should be the exact duplicate of the query version

+1 for sure. Also, a lot of this issue seems very similar to "Query subscriptions" https://github.com/supabase/realtime-js/issues/221

pedrovivaldi commented 1 year ago

I could use this feature as well