Search code examples
react-nativejwtasyncstorage

AsyncStorage doesn't return null at first start


I'm making a login using a JWT and deviceStorage, it's working okay but every time I start the app, and with JWT removed from deviceStorage, it start as if already logged in. The problem is that the get method in deviceStorage returns a promise, so I need to either make the get method return null if empty or have my program know if it's a string or a promise

APP.JS

import 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import React, { useState, useEffect } from 'react';
import Login from './src/Pages/Login';
import LoggedIn from './src/Pages/LoggedIn';
import deviceStorage from './src/Service/deviceStorage';

const App = () => {
  
  const [JWT, setJWT] = useState(null);

  useEffect(() => {
    const checkJWT = () => {
    setJWT(deviceStorage.getValue())
  }
  checkJWT()
  }, []

  );
  
  const checkJWT = () =>{
    if (!JWT || JWT === null || JWT === "") {
      return <Login setJWT={setJWT} />
    }else if (JWT){
      return <LoggedIn JWT={JWT} setJWT={setJWT} />
    }
  }

  return (
    <SafeAreaProvider>
    {checkJWT()}
    </SafeAreaProvider>
  )
}

export default App

DEVICESTORAGE

import AsyncStorage from '@react-native-async-storage/async-storage';
const key = 'currentUser';

const deviceStorage = {
  
    async saveItem(value) {
        try {
          const jsonValue = JSON.stringify(value)
          await AsyncStorage.setItem(key, jsonValue);
        } catch (error) {
          console.log('AsyncStorage Error: ' + error.message);
        }
        console.log('Done saving Value.')
      },

      async getValue() {
        try {
          return await AsyncStorage.getItem(key)
        } catch(e) {
          console.log('AsyncStorage Error: ' + e.message);
        }
      
        console.log('Done getting value.')
      },
      async removeValue() {
        try {
          await AsyncStorage.removeItem(key)
        } catch(e) {
          console.log('AsyncStorage Error: ' + e.message);
        }
      
        console.log('Done removing Value.')
      }

      
};

export default deviceStorage;

I hope someone can help me with this


Solution

  • As you pointed out, the get method of deviceStorage returns a promise currently. I think you can do one of these:

    If useEffect can accept an async method I think this should work:

    useEffect(async () => {
        const checkJWT = () => {
            setJWT(await deviceStorage.getValue())
        }
        checkJWT()
    }, []);
    

    If not, then something like this should work:

    useEffect(() => {
        const checkJWT = () => {
           deviceStorage.getValue().then(value => setJWT(value));
        }
        checkJWT()
      }, []);
    

    I haven't checked that anywhere if that works, but something along those lines should do the trick. You should make sure that you indeed put a JWT in your setJWT method and not a Promise. Or maybe you could change your setJWT method so it knows, that if it received a promise then you have to wait for the result.