Authenticated user shows up in console.log but can't access the object

Viewed 163

I'm using Supabase for authentication and I get a user object when logging in. This is how it looks like:

{
"id": "cb43b195-22cc-48c8-946a-d323f70165bd",
"aud": "authenticated",
"role": "authenticated",
"email": "joe@*******.com",
"email_confirmed_at": "2022-01-26T18:34:31.105402Z",
"phone": "",
"confirmed_at": "2022-01-26T18:34:31.105402Z",
"last_sign_in_at": "2022-02-01T18:00:27.998776Z",
"app_metadata": {
    "provider": "github",
    "providers": [
        "github"
    ]
},
"user_metadata": {
    "avatar_url": "https://avatars.githubusercontent.com/u/93337091?v=4",
    "email": "joe@*******.com",
    "email_verified": true,
    "full_name": "Joe",
    "iss": "https://api.github.com",
    "name": "Joe",
    "preferred_username": "joe",
    "provider_id": "93337091",
    "sub": "93337091",
    "user_name": "joe"
},
"identities": [
    {
        "id": "93337091",
        "user_id": "cb43b195-22cc-48c8-946a-d323f70165bd",
        "identity_data": {
            "avatar_url": "https://avatars.githubusercontent.com/u/93337091?v=4",
            "email": "joe@*******.com",
            "email_verified": true,
            "full_name": "Joe",
            "iss": "https://api.github.com",
            "name": "Joe",
            "preferred_username": "joe",
            "provider_id": "93337091",
            "sub": "93337091",
            "user_name": "joe"
        },
        "provider": "github",
        "last_sign_in_at": "2022-01-26T18:34:31.102361Z",
        "created_at": "2022-01-26T18:34:31.102403Z",
        "updated_at": "2022-01-26T18:34:31.102403Z"
    }
],
"created_at": "2022-01-26T18:34:31.098348Z",
"updated_at": "2022-01-26T18:37:12.766+00:00",
"username": "joe",
"avatar_url": "0.181358731179603.png",
"website": null }

I'm trying to access any property but for instance, if I try to render {user.username} I get a "Cannot read username property of null" error.

Any idea why that happens?

This is the context that gives the user info - I'm using it to provide the auth data:

import { createContext, useState, useEffect, useContext } from "react";
import { supabase } from "../utils/supabase";
import { useRouter } from "next/router";

const Context = createContext();

const Provider = ({ children }) => {
  const router = useRouter();
  const [user, setUser] = useState(supabase.auth.user());

  useEffect(() => {
    const getUserProfile = async () => {
      const sessionUser = supabase.auth.user();

      if (sessionUser) {
        const { data: profile } = await supabase
          .from("profiles")
          .select("*")
          .eq("id", sessionUser.id)
          .single();

        setUser({
          ...sessionUser,
          ...profile,
        });
      }
    };

    getUserProfile();

    supabase.auth.onAuthStateChange(() => {
      getUserProfile();
    });
  }, []);

  const login = async () => {
    await supabase.auth.signIn({
      provider: "github",
    });
  };

  const logout = async () => {
    await supabase.auth.signOut();
    setUser(null);
    router.push("/");
  };

  const exposed = {
    user,
    login,
    logout,
  };

  return <Context.Provider value={exposed}>{children}</Context.Provider>;
};

export const useUser = () => useContext(Context);

export default Provider;

Thanks!

1 Answers

Could be because you are trying to access the user information before the API returns the data. In the component you are rendering the user data, check if the user exists first before returning your component.

if(!user) {
  return <p>Loading...</p>
  }
Related