I am running into some problems with saving my jwt upon log-in
as you can see i call two different functions to get and save my jwt and one more for debug purposes
What i dont get is why when i press a single time on my connection button it doesn’t save the jwt but it does upon my second press of the button ?
Do you happen to know how i can fix that ?
here is my LoginScreen code :
import { Button, KeyboardAvoidingView, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'
import React, { useEffect, useState } from 'react'
import { auth } from '../firebase'
import { onAuthStateChanged, signInWithEmailAndPassword } from 'firebase/auth'
import { useNavigation } from '@react-navigation/native'
import * as SecureStore from 'expo-secure-store';
const LoginScreen = () => {
const [token, setToken] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState('')
const navigation = useNavigation();
async function getToken(){
try {
const user = auth.currentUser;
if (user) {
const idTokenResult = await user.getIdTokenResult();
setToken(idTokenResult.token);
console.log('token set')
}
} catch (error) {
console.log(error);
}
}
async function saveToken(jwt, token) {
await SecureStore.setItemAsync(jwt, token);
}
async function getValueFor(key) {
let result = await SecureStore.getItemAsync(key);
if (result) {
console.log("🔐 Here's your value in LoginScreen 🔐 n" + result);
} else {
console.log('No values stored under that key.');
}
}
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, user => {
if (user){
console.log('here')
}
})
// unsubscribe va stopper le listner firebase lorsque l'utilisateur sort de la page login
return unsubscribe
}, [])
const handleLogin = async () => {
await signInWithEmailAndPassword(auth, email, password)
.then(userCredentials => {
const user = userCredentials.user;
getToken()
console.log('firebase : logged in')
})
.catch(error => setError(error.message))
saveToken('jwt', token);
getValueFor('jwt');
}
return (
<KeyboardAvoidingView
style={styles.container}
behavior="padding">
<View style={styles.inputContainer}>
{error ? <Text style={{ color: 'red' }}>{error}</Text> : null}
<TextInput
placeholder='Identifiant'
value={email}
onChangeText={text => setEmail(text)}
style={styles.input}
/>
<TextInput
placeholder='Mot de passe'
value={password}
onChangeText={text => setPassword(text)}
style={styles.input}
secureTextEntry
/>
</View>
<View style={styles.textView}>
<TouchableOpacity style={styles.text} onPress={() => navigation.navigate('ForgotPassword')}>
<Text>Mot de passe oublié ?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.text} onPress={() => navigation.navigate('Register')}>
<Text>Pas encore de compte ? Inscris-toi ici.</Text>
</TouchableOpacity>
</View>
<View
style={styles.buttonContainer}>
<TouchableOpacity
onPress={handleLogin}
style={styles.button}
>
<Text style={styles.buttonText}>Connexion</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
)
}
export default LoginScreen
and a screenshot of my terminal when I press a single time my button :
thank you in advance
2
Answers
I am answering my own post in the event that someone happens to have the same trouble,in the end it is bad habit to call an async methond after a ".then", to fix that i needed to store the result of my call within a const
The previous code are the changes made on my "LoginScreen" file, by storing my getToken result in the "userToken" const my problem went away
I am still open to any more in-depth explanation that anyone could have, thx
Since the functions are
async
, then you need to await for the token to be saved in the store. Therefore change your method to the following: