Day 2 / 14 of building my full-stack application challenge

Day 2 / 14 of building my full-stack application challenge

Todays Tasks

  1. Authentication
  2. Create user state
  3. Even on refresh maintain user login info
  4. SignIn component
  5. SignUp component
  6. Welcome page component - protected route only if you're logged in has access too.

My Experience

Boy o boy... user management and authentication can get so mind-boggling, most especially when you're doing it with a database you just use for the first time. I usually prefer video tutorials to learn a new tool but there's not so much on supabase yet. So today was a lot of reading the documentation for supabase and a lot of trial and error. Overall, it seems like I got the job done.

How did I get authentication to work

Knowing how to read the documentation and examples provided by other developers is essential in programming. The supabase documentation is very easy to follow and has a lot of examples for using JavaScript. They have many examples of how to create user management, but I ended up hacking it.

The hardest part

The most difficult was finding a way to maintain userInfo. For now, I know I need to just either maintain the user_id or the user login token - something I need to research a bit more on, but my overall goal was to maintain global state quickly. For a simple, non-complex global state, I choose to use the context API instead of setting up all of redux.

I created two files inside my context folder:

  1. UserContext
  2. UserAuthProvider
// userContext.ts
import { createContext } from "react";

export const UserContext = createContext(null);
// UserAuthProvider.ts
import { AuthSession } from "@supabase/supabase-js";
import React, { useEffect, useState } from "react";
import { User } from "../../utils/constants";
import { UserContext } from "./userContext";
const UserAuthProvider = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [session, setSession] = useState<AuthSession | null>(null);

  useEffect(() => {
    const userFromLocalStorage = window.localStorage.getItem("userAuth");
    if (userFromLocalStorage) {
      setUser(JSON.parse(userFromLocalStorage));
    }
  }, []);

  useEffect(() => {
    const userFromLocalStorage = window.localStorage.getItem("userAuth");
    if (!userFromLocalStorage) {
      window.localStorage.setItem("userAuth", JSON.stringify(user));
    }
    window.localStorage.setItem("userAuth", JSON.stringify(user));
  }, [user]);

  return (
    <UserContext.Provider value={{ user, setUser, session, setSession }}>
      {children}
    </UserContext.Provider>
  );
};

export default UserAuthProvider;

Screenshot (373).png

As you can see, I am using local storage to help maintain the user information that I get when a user logs in. Supabase also adds its session to localStorage, which holds the login token, but I believe only lasts for 60 minutes. So in all honestly, I really need to check on how that all works.

Traditionally, I just store the users jwt token but for now, just being able to maintain some auth is a great start.

Biggest Takeways:

  1. READ the DOC's. I never liked reading the docs, but I am starting to like it. The more I force myself to read the docs the more time I can save, especially if I already know where to look for.
  2. Read other people's code - it is not cheating! Learning how other people write code is a great way to learn from other people. You get to see why someone did something and alternative ways compared to how you would do it.
  3. There are a lot more examples of code on GitHub compared to youtube tutorials. Yes, learning from a video can be easy, but if habitual only using youtube as your reference, it may get harder when you use a very new tool that has few examples