After refreshing the page I lose the ability to retrieve user information

At first my webapp looses login after refresh, then I read some topics on how to set up social logins and I solved.
But now I have a different problem. Here is some code to explain better:

const { user } = useAuth0();

const sub = user.sub;

If I refresh I get: “TypeError: Cannot read property ‘sub’ of undefined
However, the user is still logged, in fact if I go back and then forward using the browser arrows, the page reloads without errors.
If I load login/signup page url, the “logout” button appears as the user is still logged.
I realized that maybe it’s not clear. The button if the user is not logged display"login", if user is logged display “logout”.

EDIT: From other tests I have done I have noticed this. If I refresh a component (use React.js) that retrieve user info like: user.name, user.sub ecc… I get error; but if I load a different component first and then the one using user. then it works.

Concrete example: The UserInfo.js component crashes after the refresh, but if I first access the Dashboard.js component and then click on UserInfo through the sidebar then it works and load it without any error.

How can I avoid this error? And above all why does it occur if the user apparently has not logged out?

EDIT: I think I have identified the problem but I don’t know how to solve it: when the page is rendered, the response from the Auth0 API still not obtained and therefore the claim user.sub is undefined.
In the SDK there’s loading but I don’t know how to use it and I haven’t found any help about it.

My solution: Set the isLoading as a dependency within the hook and let the fetching be conditional on isLoading being false

import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import {useState, useEffect} from 'react'


const CheckProfile = () => {
  const { user, isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();
  const [userMetadata, setUserMetadata] = useState(null);

  useEffect(() => {
    const getUserMetadata = async () => {
      const domain = "yourDomain.us.auth0.com";
      
  
      try {
        const accessToken = await getAccessTokenSilently({
          audience: `https://${domain}/api/v2/`,
          scope: "read:current_user",
        });
  
        const userDetailsByIdUrl = `https://${domain}/api/v2/users/${user.sub}`;
  
        const metadataResponse = await fetch(userDetailsByIdUrl, {
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        });
  
        const { user_metadata } = await metadataResponse.json();
  
        setUserMetadata(user_metadata);
      } catch (e) {
        console.log(e.message);
      }
    };
    if(isLoading==false) {getUserMetadata();}
  }, [isLoading]);


  if (isLoading) {
    return <div>Loading ...</div>;
  }

  return (
    isAuthenticated && (
      <div>
        <img src={user.picture} alt={user.name} />
        <h2>{user.name}</h2>
        <p>{user.email}</p>
        <h3>User Metadata</h3>
        {userMetadata ? (
          <pre>{JSON.stringify(userMetadata, null, 2)}</pre>
        ) : (
          "No user metadata defined"
        )}
      </div>
    )
  );
};

export default CheckProfile;
2 Likes

Thanks for sharing it with the rest of community!

This saved me! Thank you so much!

Perfect! Glad to hear that!