Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How should I subscribe to a query with embedded resources? #396

Open
jameshfisher opened this issue Mar 4, 2024 · 3 comments
Open

How should I subscribe to a query with embedded resources? #396

jameshfisher opened this issue Mar 4, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@jameshfisher
Copy link

Thanks for this library!

The docs don't describe embedded resources / joins, or have any examples of this. I need to implement a realtime subscription to a query that includes an embedded resource. I see that useSubscriptionQuery works, but it's unclear to me whether this is the recommended way to implement this.

To Reproduce

  1. Create a hook like this:
import {
  useQuery,
  useSubscription,
} from "@supabase-cache-helpers/postgrest-swr";
import { useSupabase } from "./supabase-provider";

export function useRealtimeEmployees() {
  const { supabase } = useSupabase();
  useSubscription(
    supabase,
    `some-channel-name`,
    { event: "*", table: "employee", schema: "public" },
    ["id"]
  );
  const { data: realtimeEmployees } = useQuery(
    supabase.from("employee").select("id, name, company (name)").throwOnError()
  );
  return realtimeEmployees;
}
  1. Insert a row in the employee table.

Expected behavior

The realtimeEmployees is updated to include the inserted row.

Actual behavior

The client receives a WebSocket message from Supabase, but the realtimeEmployees is not updated.

Additional context

The cause is that the query has a join ("embedded resource"?) with another table company. So when the new row is received, the client doesn't have information about the corresponding row in company. If the query is changed to just .select("id, name"), inserts work as expected.

So in a sense, this is not a bug, and the code couldn't possibly work. What I'm looking for is advice on the best way to implement a subscription that includes embedded resources.

One option that seems to work is useSubscriptionQuery. My main confusion is that the documentation says "The main use case for this hook is Computed Columns", and doesn't mention joins at all - implying there is some better way to handle joins.

@jameshfisher jameshfisher added the bug Something isn't working label Mar 4, 2024
@jameshfisher
Copy link
Author

Another possible approach: don't use embedded resources / joins, and instead do the join client-side, like:

  • Every employee row corresponds to a React element
  • Each element has a realtime subscription to the company of its employee

But this follows the bad "N+1 queries" pattern that I think would result in pretty bad performance.

@jameshfisher
Copy link
Author

Ok, I've discovered a reason that useSubscriptionQuery doesn't work for this: delete events don't seem to re-trigger the query. I see that the client receives the delete event, but it does not re-run the query, and the realtimeEmployees is never updated.

Strictly, I'm not sure it would need to re-run the query against the Supabase API. A delete event gives supabase-cache-helpers everything it needs to just drop the row from the query result. But it doesn't do that.

@psteinroe
Copy link
Owner

hey, thanks for opening the issue.

One option that seems to work is useSubscriptionQuery. My main confusion is that the documentation says "The main use case for this hook is Computed Columns", and doesn't mention joins at all - implying there is some better way to handle joins.

actually - its also the preferred way to handle joins! would you mind adding this to the docs?

Ok, I've discovered a reason that useSubscriptionQuery doesn't work for this: delete events don't seem to re-trigger the query. I see that the client receives the delete event, but it does not re-run the query, and the realtimeEmployees is never updated.

can you share your code for this? this sounds like a bug to me, because DELETE events should indeed update related queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants