Search code examples
reactjsreact-nativeauthenticationasyncstorage

Problem when trying to use AsyncStorage with react native


I am new to react native and I tried to make my first app. I am in the process of making the login/signup pages. I am trying to use AsyncStorage to make the app remember the user. I tested out this code-

import { StatusBar } from 'expo-status-bar'
import { StyleSheet, Text, View, FlatList, Image, Button, Pressable, ScrollView  } from 'react-native';
import React, {useState, useEffect} from 'react'
import { TextInput } from 'react-native-gesture-handler';
import AsyncStorage from '@react-native-async-storage/async-storage';








export default function Login(props) {

  const message = props.navigation.getParam('message', null)
  const [ username, setUsername ] = useState("")
  const [ password, setPassword ] = useState("")

  setStringValue = async(value, user) => {
    try {
      
      await AsyncStorage.setItem( user, value)
    } catch(e){
      console.log(e)
    }
  }

  const getData = async (user) => {
    try {
      const value = await AsyncStorage.getItem(user)
      if(value !== null) {
        return value
      } else {
        return false
      }
    } catch(e) {
      console.log(e)
    }
  }

  

  const log = () => {

    fetch(`http://192.168.5.223:8000/home/login/`, {
      method: 'POST',
      headers: {
          "Content-Type": 'application/json'
         },
      body: JSON.stringify({ username: username, password: password}),
  })
  .then( res => res.json())
  .then( res => {
    console.log(res)
    
    if (res.valid === true){

      setStringValue(username, username)

      let ch = getData(username)

      console.log(ch)
      

      
      
      
      
      if (res.set === true){
        props.navigation.navigate("Home", {"user": username})
      } else {
        props.navigation.navigate("Profile", {"user": username})
      }
      
    } else {
      props.navigation.navigate("Login", {'message': "username/password are incorrect"})
    }
    

  })
  .catch( error => console.log(error))
  



  



  }

  const sign = () => {

    props.navigation.navigate("Signup")

  }

  return (
    <View style={styles.container}>
      <ScrollView style={styles.scroll} >
      <View style={styles.main}>
      <Text style={styles.error}>{message}</Text>  
      <Text style={styles.label}>
        Username: 
      </Text>
      <TextInput style={styles.input} placeholder="Username" 
        onChangeText={ text => setUsername(text)} value={username}
        autoCapitalize={'none'}
         />
      
      <Text style={styles.label}>Password:</Text>
      <TextInput style={styles.input} placeholder="Password" onChangeText={ text => setPassword(text)}
        value={password} secureTextEntry={true} autoCapitalize={'none'}
      />

      
      <Button onPress={ () => log()} title="Login"></Button>
      </View>
      </ScrollView>
      <View style={styles.footer}>
        <Button onPress={ () => sign()} title="Don't have an acount? Sign up now" />
      </View>
      <StatusBar style="auto"/>
    </View>


  )


}

Login.navigationOptions = screenProps => ({
  headerLeft: () => null,
  gestureEnabled: false,
  headerStyle: {
    backgroundColor: 'black'
  },
  headerTintColor: 'white',

})

But the AsyncStorage logged -

Promise {

"_U": 0,

"_V": 0,

"_W": null,

"_X": null,

} How can I get this to work?


Solution

  • getData and setStringValue are asynchronous functions. So you have to put await before calling them and also mark callback function as async.

    so Please try this log function

    const log = () => {
    
        fetch(`http://192.168.5.223:8000/home/login/`, {
            method: 'POST',
            headers: {
                "Content-Type": 'application/json'
            },
            body: JSON.stringify({ username: username, password: password }),
        })
            .then(res => res.json())
            .then( async (res) => {
                console.log(res)
    
                if (res.valid === true) {
    
                    await setStringValue(username, username)
    
                    let ch = await getData(username)
    
                    console.log(ch)
    
                    if (res.set === true) {
                        props.navigation.navigate("Home", { "user": username })
                    } else {
                        props.navigation.navigate("Profile", { "user": username })
                    }
    
                } else {
                    props.navigation.navigate("Login", { 'message': "username/password are incorrect" })
                }
    
            })
            .catch(error => console.log(error))
    
    }
    

    Full Code

    import { StatusBar } from 'expo-status-bar'
    import React, { useState, useEffect } from 'react'
    import { TextInput } from 'react-native-gesture-handler';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    import { StyleSheet, Text, View, FlatList, Image, Button, Pressable, ScrollView } from 'react-native';
    
    
    export default function Login(props) {
    
        const message = props.navigation.getParam('message', null)
        const [username, setUsername] = useState("")
        const [password, setPassword] = useState("")
    
        const setStringValue = async (value, user) => {
            try {
    
                await AsyncStorage.setItem(user, value)
            } catch (e) {
                console.log(e)
            }
        }
    
        const getData = async (user) => {
            try {
                const value = await AsyncStorage.getItem(user)
                if (value !== null) {
                    return value
                } else {
                    return false
                }
            } catch (e) {
                console.log(e)
            }
        }
    
        const log = () => {
    
            fetch(`http://192.168.5.223:8000/home/login/`, {
                method: 'POST',
                headers: {
                    "Content-Type": 'application/json'
                },
                body: JSON.stringify({ username: username, password: password }),
            })
                .then(res => res.json())
                .then(async (res) => {
                    console.log(res)
    
                    if (res.valid === true) {
    
                        await setStringValue(username, username)
    
                        let ch = await getData(username)
    
                        console.log(ch)
    
                        if (res.set === true) {
                            props.navigation.navigate("Home", { "user": username })
                        } else {
                            props.navigation.navigate("Profile", { "user": username })
                        }
    
                    } else {
                        props.navigation.navigate("Login", { 'message': "username/password are incorrect" })
                    }
    
                })
                .catch(error => console.log(error))
    
        }
    
        const sign = () => {
    
            props.navigation.navigate("Signup")
    
        }
    
        return (
            <View style={styles.container} >
                <ScrollView style={styles.scroll} >
                    <View style={styles.main}>
                        <Text style={styles.error}> {message} </Text>
                        < Text style={styles.label} >
                            Username:
                        </Text>
                        <TextInput style={styles.input} placeholder="Username"
                            onChangeText={text => setUsername(text)} value={username}
                            autoCapitalize={'none'}
                        />
    
                        <Text style={styles.label}> Password: </Text>
                        <TextInput style={styles.input} placeholder="Password" onChangeText={text => setPassword(text)}
                            value={password} secureTextEntry={true} autoCapitalize={'none'}
                        />
    
    
                        <Button onPress={() => log()} title="Login" > </Button>
                    </View>
                </ScrollView>
                < View style={styles.footer} >
                    <Button onPress={() => sign()} title="Don't have an acount? Sign up now" />
                </View>
                < StatusBar style="auto" />
            </View>
        )
    }
    
    Login.navigationOptions = screenProps => ({
        headerLeft: () => null,
        gestureEnabled: false,
        headerStyle: {
            backgroundColor: 'black'
        },
        headerTintColor: 'white',
    
    })