Home > Mobile >  Problems with login/logout in React Native AsyncStorage with Django backend
Problems with login/logout in React Native AsyncStorage with Django backend

Time:08-24

I am building by first React Native app and I am in the process of making the login/logout functions of the app. I am trying to us AsyncStorage to remember a user. But I am facing a few problems:

1- when I try to login put the user in AsyncStorage, it works and I get the username, however when I try to use it without login in(so it remembers the user) I get Promise {

"_U": 0,

"_V": 0,

"_W": null,

"_X": null,

}

2- When I try to use the AsyncStorage.removeItem() and then close the app, the app still automatically logs the user in.

heres my code:

login.js

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) => {
        try {

            await AsyncStorage.setItem('@userauthkey', value)
        } catch (e) {
            console.log(e)
        }
    }

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

    const ch = async () => {
        const ch = await getData()
        return ch
    }

    console.log(ch())

    const c  = ch()

    if (c == false){
        console.log('login')
    } else {
        console.log(c)
        props.navigation.navigate('Home')
    }

   

    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)

                    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',

})

const styles = StyleSheet.create({
  error: {
    textAlign: 'center',
    color: 'red',
  },

  main: {
    paddingTop: 145,
    paddingHorizontal: 5,
  },

  container: {
    flex: 1, 
    backgroundColor: 'black',
    
  },
  
  scroll: {
    backgroundColor:'#'
  },

  footer: {
    borderTopColor: '#fff',
    padding:35,
  },

  label: {
    fontSize: 24,
    color: "white",
    padding: 10,

  },

  input: {
    fontSize: 24,
    backgroundColor: "white",
    padding: 10,
    margin: 10,
    borderRadius: 5,
  },


  
});

home.js-

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';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { faUser } from '@fortawesome/free-regular-svg-icons';
import { faComment } from '@fortawesome/free-regular-svg-icons';





export default function Home(props) {

  
  
  const [ current, setCurrent ] = useState("profile")
  const user = props.navigation.getParam("user", null)


  const curr = (cur) => {
    setCurrent(cur)
  }

  

  const gprof = (user) => {
    fetch(`http://192.168.5.223:8000/home/checkprofile/`,{
      method: 'POST',
      headers: {
        "Content-Type": 'application/json',
       },
       body: JSON.stringify({'user':user}),

    } )
    .then( res => res.json())
  .then( res => {
    console.log(res.profile)
    console.log(res.sets)
    if (res.sets === false){
      props.navigation.navigate('Profile')
    }

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

  
  const logout = async () => {
    try {
      await AsyncStorage.removeItem('@userauthkey')
      props.navigation.navigate('Login')
    } catch(e){
      console.log(e)
    }
  }

  if(current === "profile"){
       return (
        <View style={styles.container}>
            <ScrollView style={styles.scroll} >
                <Text> profile {user} </Text>
                <Pressable onPress={ () => logout()}>
                <Text>Logout</Text>
                </Pressable>
            </ScrollView>
            
            <View style={styles.footer}>
              <Pressable onPress={() => curr('profile')}>
              <FontAwesomeIcon icon={faUser} style={{color: 'white'}}/>
              </Pressable>

              
              <Pressable onPress={() => curr('messanger')}>
              <FontAwesomeIcon icon={faComment} style={{color: 'white',}} />
              </Pressable>
            </View>
            <StatusBar style="auto"/>
        </View>
    )
  } else if(current === "posts"){
    return (
        <View style={styles.container}>
            <ScrollView style={styles.scroll} >
                <Text> posts {user} </Text>

            </ScrollView>
            <View style={styles.footer}>
        
            </View>
            <StatusBar style="auto"/>
        </View>
    )
  } else if (current === "messanger"){
    return (
        <View style={styles.container}>
            <ScrollView style={styles.scroll} >
                <Text> messanger {user} </Text>

            </ScrollView>
            <View style={styles.footer}>
              <Pressable onPress={() => curr('profile')}>
              <FontAwesomeIcon icon={faUser} style={{color: 'white'}}/>
              </Pressable>
              
              <Pressable onPress={() => curr('messanger')}>
              <FontAwesomeIcon icon={faComment} style={{color: 'white',}} />
              </Pressable>
            </View>
            <StatusBar style="auto"/>
        </View>
    )
  }

}

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

const styles = StyleSheet.create({
    container: {
      flex: 1, 
      backgroundColor: '#999',
      
    },
    
    scroll: {
      backgroundColor:'#'
    },
  
    footer: {
      borderTopColor: '#fff',
      padding:35,
      flexDirection: 'row',
    
    },
  
    label: {
      fontSize: 24,
      color: "white",
      padding: 10,
  
    },
  
    input: {
      fontSize: 24,
      backgroundColor: "white",
      padding: 10,
      margin: 10,
      borderRadius: 5,
  
    },
  
  
    
  });

How can I solve these issues?

CodePudding user response:

The ch is an async function. When you call console.log(ch()) it is expectedly print Promise object.

Then you check the result:

const c = ch();
if (c == false) { 
...
} else {
  props.navigation.navigate('Home')
}

The c is a Promise object thus you are navigating to Home.

In React you should not run side-effects directly inside the render body. Use effects for this:

useEffect(() => {
  const ch = async () => {
    const c = await getData();
    if (c) {
      props.navigation.navigate("Home");
    }
  };
  ch();
}, [...]); // be careful with dependencies

CodePudding user response:

Check the user is login or not in useEffect

e.g.

useEffect(() => {
        checkLogin()
            .then(res => {
                if (res == true) {
                    //Navigate to home screen code
                }
                else {
                    //Navigate to Login/Signup screen code
                }
            })
    }, [])

Check login method

const checkLogin = async () => {
        const res = await AsyncStorage.getItem('@userauthkey')
        return res
    }

App.js

export default function App() {
    React.useEffect(() => {
        checkLogin()
            .then(res => {
                if (res == true) {
                    //Navigate to home screen code
                }
                else {
                    //Navigate to Login/Signup screen code
                }
            })
    }, [])

    const checkLogin = async () => {
        const res = await AsyncStorage.getItem('@userauthkey')
        return res
    }

    //rest of your code
}
  • Related