supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
2.83k stars 219 forks source link

Intermittent empty fetch response #1019

Closed jonlaing closed 1 week ago

jonlaing commented 2 weeks ago

Bug report

Describe the bug

I have an expo app in which I have a lists of posts that you can click into. The list of posts works fine. However, when clicking into a post and I try to fetch an individual post, the first time will be successful, but each subsequent fetch will be unsuccessful, even when going back to the same post.

To Reproduce

import { PostgrestError, QueryData } from "@supabase/supabase-js";
import { supabase } from "../lib/supabase";
import { useEffect, useState } from "react";

const query = supabase.from("Post").select(`
  id,
  summary,
  date,
  Profile (
    id,
    name,
    Image (
      thumbnail,
      index
    )
  ),
  Image (
    full,
    thumbnail,
    index
  ),
  Like (profileId),
  Post (count)
`);

export type Post = QueryData<typeof query>[number];

export default function usePost(postId?: string) {
  const [post, setPost] = useState<Post | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<PostgrestError | null>(null);

  useEffect(() => {
    if (!postId) {
      return;
    }

    (async () => {
      console.log("FETCHING", postId);
      const { data, error, status } = await query.eq("id", postId).single();

      setLoading(false);

      if (error) {
        console.error("ERROR", error, "STATUS", status);
        setError(error);
        return;
      }

      console.log("POST:", data);
      setPost(data);
    })();
  }, [postId]);

  return { post, loading, error };
}

On initial fetch I receive the post as expected:

POST: {"Image": [], "Like": [], "Post": [{"count": 1}], "Profile": [{"Image": [Array], "id": "92afb876-133b-40bb-9bfc-a1a8146d6526", "name": "jonlaing"}], "date": "2024-04-18T01:06:08.018", "id": "d7ddb757-75de-4218-abb5-0b60b975cc3a", "summary": "Dhjjfgjbdd"}

But if I go back, and try again, I'll receive an error:

ERROR {"code": "PGRST116", "details": "The result contains 0 rows", "hint": null, "message": "JSON object requested, multiple (or no) rows returned"} STATUS 406

Expected behavior

I would expect the fetch to return a post given a valid id. I've checked and it is indeed using valid id's, as evidenced by it working the first time.

Screenshots

If applicable, add screenshots to help explain your problem.

System information

Additional context

I'm using expo-router and the page in question is named /posts/[id].tsx so I don't know if that's relevant. I have the app logging the postId, and it's correct every time, so I can't imagine there's an issue there, but I could be wrong.

Also, I used Prisma for all of my database creation and migration, so also not sure if that's relevant.

Thanks!

jonlaing commented 1 week ago

Okay, I just figured out what I did wrong. The query variable is instantiated at load time of the file, rather than at runtime of the useEffect, so it's essentially chaining the eq('id', postId) portion every time the useEffect runs, rather than building a new query each time. That's my bad. Closing the issue, but leaving this for posterity in case anyone else makes the silly mistake I did.