DEV Community

amanbhoria
amanbhoria

Posted on

2

Handling Asynchronous State with User Roles in React Native with Firebase

In my recent project, I encountered an interesting challenge that I’m sure many of you have faced—fetching data based on user roles in a React Native app.

I’d added user roles (regular, admin) to my app, and as an admin, I needed to fetch all jobs in the system.

The logic to do this was simple—check the logged-in user’s role and fetch data accordingly. But what I didn’t expect was how React’s asynchronous behavior would impact my logic.

Here's the initial code snippet I was working with:

  const [loggedInUser, setLoggedInUser] = 
useState<Partial<User> | null>(null);

const fetchJobs = async () => {
    try {
      let firebaseService = await new FirebaseService();
      let jobsList: Job[] = [];

      if (loggedInUser?.role == UserRoles.ADMIN)
         jobsList = await firebaseService.listAllJobs();
      else 
         jobsList = await firebaseService.listSingleUserJob();

      setJobs(jobsList);
      setFilterJobs(jobsList);
    } catch (error) {
      console.error('Error fetching jobs:', error);
    } finally {
      setRefreshing(false);
      setIsLoading(false);
    }
  };

useEffect(() => {
    const fetchUser = async () => {
      try {
        let user = await returnLoggedUser();
        setLoggedInUser(user);
      } catch (error) {
        console.error('Failed to fetch user', error);
      }
    };

    fetchUser();
  }, []);

  useFocusEffect(
    useCallback(() => {
      if (!hasRun) {
        fetchJobs();
        setHasRun(true);
      }, []
  );
Enter fullscreen mode Exit fullscreen mode

UseFocusEffect runs when the screen gains the focus.

In theory, it made sense. But what I wasn’t ensuring was that loggedInUser would always be defined before I tried to fetch jobs. Because useEffect and useFocusEffect run asynchronously, there was no guarantee that loggedInUser would be set by the time fetchJobs() ran

That's how this react's asynchronous behavior comes into picture.

I needed to ensure that loggedInUser had been set before proceeding with the job-fetching logic.

By adding a check for loggedInUser, I made sure that fetchJobs only runs when the user information is available:

useFocusEffect(
    useCallback(() => {
      if (loggedInUser && !hasRun) {
        fetchJobs();
        setHasRun(true);
      }, [loggedInUser]
  );
Enter fullscreen mode Exit fullscreen mode

Keep Building!

Image of Quadratic

Free AI chart generator

Upload data, describe your vision, and get Python-powered, AI-generated charts instantly.

Try Quadratic free

Top comments (0)

Neon image

Set up a Neon project in seconds and connect from a Node.js application

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Dive into this thoughtful article, cherished within the supportive DEV Community. Coders of every background are encouraged to share and grow our collective expertise.

A genuine "thank you" can brighten someone’s day—drop your appreciation in the comments below!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found value here? A quick thank you to the author makes a big difference.

Okay