skip to Main Content

I am new to React Native and app development. So I am making a basic app that once opened, a modal opens up for use to login. User authenticates with Supabase, and then modal goes away to user can start using the app. The app will use the user’s data, such as his name, his privileges and things like that.
My fundamental question is, do I need to locally store the ‘session’ data and transfer it to other views/screens? or just transfer the access token and make requests to database for other interactions such as getting user details etc. How does it work generally, I think it is not down to React Native only and generally the app dev approach.

2

Answers


  1. I suggest separate the authentication block from the rest of your code. Keep it simple by using a Context and Provider component:

    import React, { createContext, useEffect, useState, useContext } from "react";
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    import { logIn, logOut } from "../services/api/auth";
    import { loginAndSaveUser } from "../utils/Auth/loginAndSaveUser";
    
    const AuthContext = createContext();
    
    const AuthProvider = ({ children }) => {
    // this provides current session data to its children
    const [user, setUser] = useState(null);
    
    // auto login when opening the app
    useEffect(() => {
        _autoLogin();
    }, []);
    
    const _autoLogin = async () => {
        try {
            // this read data from storage
            const user = await AsyncStorage.getItem('user');
            if (user) {
                const response = await logIn(user.username, user.password);
                if (response.ok) {
                    // now you provide the user data to children component
                    setUser({
                        username: String(username),
                        password: String(password),
                        userId: String(response.text.userData.id),
                        token: String(response.text.accessToken)
                    });
                } else {
                    // this means the data in storage is not right
                    await AsyncStorage.removeItem('user');
                }
            }
        } catch (error) {
            console.log(error);
        }
    }
    
    const _signIn = async (username, password) => {
        try {
            const response = await loginAndSaveUser(username, password);
            if (response.status === 'success') {
                setUser(response.userData);
            } else {
                setUser(null);
            }
            return response;
        } catch (error) {
            console.log(error);
        }
    }
    
    // choose logout -> delete data
    const _logOut = async () => {
        try {
            const token = user.token;
            if (token) {
                const response = await logOut(token);
                await AsyncStorage.removeItem('user');
                setUser(null);
            } else {
                setUser(null);
                console.log("Error in logOut function (Auth): No token found for current user");
            }
        } catch (error) {
            console.log("Error in logOut function (Auth): ", error);
        }
    };
    
    const value = {
        user,
        _signIn,
        _logOut
    };
    return (
        <AuthContext.Provider value={value}>
            {children}
        </AuthContext.Provider>
    )};
    const useAuth = () => {
        const context = useContext(AuthContext);
    
        if (!context) {
            throw new Error('useAuth must be used within an AuthProvider');
        }
    
    return context;
    };
    
    export { AuthContext, AuthProvider, useAuth }; 
    

    and in children components, for example the login screen:

    const auth = useAuth();
    

    and use the data:

    const handleSignIn = async () => {
    try {
      if (!email || !password) {
        Alert.alert('Missing Infor','You may miss some fields');
        return;
      } else {
        const res = await auth._signIn(email, password);
        switch (res.status) {
          case 'success':
            break;
          case 'failed':
            ......
    
    Login or Signup to reply.
  2. Usually you would want to store these things in a persisted data storage. Meaning that these data values are kept throughout different starts of the application.

    Zustand Persist

    State managers like the Zustand one have these functionalities. You can also use other state management libraries. However, storing the accesstoken and refreshtoken for later usage is most often a must in app development.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search