useQuery data is null after page refresh

637 Views Asked by At

I have a simple function that returns the user from Firebase Auth.

export async function getCurrentUser() {
  const curUser = await projectAuth.currentUser?.getIdTokenResult();
  return curUser || null;

And a simple react query hook:

export function useCurrentUser() {
  const { isLoading, data: user } = useQuery({
    queryKey: ["user", projectAuth.currentUser?.email],
    queryFn: getCurrentUser,
    onError: (err) => console.log(err),
  });

  return { isLoading, user };
}

The idea is to only show a dashboard page only if a user is logged in. When I log in to the system the first time - it is great, the app navigates to the dashboard, I see the user in React Query Devtools and in the UI on the page. But once I refresh the page - the user is null, and no data related to the user is shown in the UI. The data shows up later after it becomes stale and then refetches.

I tried multiple approaches but none seem to be working. Seeking help as I am fairly new to this, and this issue has been pretty persistent so Im not sure whether its firebase or react query.

2

There are 2 best solutions below

1
On

It seems like you're encountering an issue where data isn't persisting after a page refresh, which is a common challenge when working with Firebase and React Query. To ensure data persistence, you need to setup your libraries to keep the data after a refresh. Below are instructions on how to do this:

1. Firebase Persistence:

Firebase Auth provides a way to persist the user's session even after a page refresh. You can set this up in your Firebase configuration. Here's how you can enable persistence:

// Enable persistence
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)

By setting Persistence.LOCAL, the user's authentication state will be cached on the user's device, making it available even after a page refresh.

2. React Query Setup:

To ensure that React Query uses the persisted user data, you need to initialize React Query with a custom cache. This is how you can do it:

import { QueryClient, QueryClientProvider } from 'react-query';

const queryClient = new QueryClient({
 defaultOptions: {
   queries: {
     refetchOnWindowFocus: false, // Disable automatic refetch on window focus
   },
 },
});

function App() {
 return (
   <QueryClientProvider client={queryClient}>
     {/* Your app code */}
   </QueryClientProvider>
 );
}

By disabling refetchOnWindowFocus, you prevent unnecessary refetches when the window regains focus, which would trigger a refetch after a page refresh.

3. Modify useCurrentUser Hook:

You should modify your useCurrentUser hook to use the queryClient you've created and cache the user data. Here's an example of how you can do this:

import { useQuery, useQueryClient } from 'react-query';

export function useCurrentUser() {
 const queryClient = useQueryClient();
 const user = queryClient.getQueryData('user');

 return user;
}

In this modified hook, you're directly accessing the cached data from the queryClient.

By following these steps, your user's data should persist across page refreshes. The Firebase persistence ensures that the user's authentication state is retained, and the React Query cache will help in displaying the user data without unnecessary refetches.

As a side note, I haven't used Firebase in a little while, and most of this is from memory, so take it with a grain of salt

0
On

The React Query cache is in memory only. If you reload the page, data is gone. If you want persistence, you'd need to opt into that with the persistQueryClient plugin:

https://tanstack.com/query/v5/docs/react/plugins/persistQueryClient