skip to Main Content

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 :

terminal screenshot

thank you in advance

2

Answers


  1. Chosen as BEST ANSWER

    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

      async function getToken(){
    try {
      const user = auth.currentUser;
        if (user) {
          const idTokenResult = await user.getIdTokenResult();
          return idTokenResult?.token
        }
      } catch (error) {
        console.log(error);
      }
    }
    
    
      const handleLogin = async () => { 
    try {
    await signInWithEmailAndPassword(auth, email, password)
    
     const userToken = await getToken();
     await SecureStore.setItemAsync('jwt', JSON.stringify(userToken));
     setToken(userToken);
    } catch (err) {
     console.log(err.message)
    }
    
    getValueFor('jwt')}
    

    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


  2. 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:

        await signInWithEmailAndPassword(auth, email, password)
        .then(async userCredentials => {
          const user = userCredentials.user;
          await getToken()
          console.log('firebase : logged in')
        })
        .catch(error => setError(error.message))
        await saveToken('jwt', token);
        await getValueFor('jwt');
    
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search