简体   繁体   中英

react native firebase not persisting user info

This is a plain vanilla user sign in app. When a user signs in, they should see the Home screen but for some reason it doesnt get to the Homescreen at all. Full App.js code is below.

I have a branching condition user? goto Home: or just show the login/signup options. The user variable has a value of 'undefined'. Does this meant he value did not persist?

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { LoginScreen, HomeScreen, RegistrationScreen } from './src/screens'
import {decode, encode} from 'base-64'
import { firebase } from './src/firebase/config'


if (!global.btoa) {  global.btoa = encode }
if (!global.atob) { global.atob = decode }

const Stack = createStackNavigator();

export default function App() {

  const [loading, setLoading] = useState(true)
  const [user, setUser] = useState(null)
  
  

  useEffect(() => {
    const usersRef = firebase.firestore().collection('users');
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        console.log(user)
        console.log('user is logged in  ')
        usersRef
          .doc(user.uid)
          .get()  
          .then((document) => {
            const userData = document.data()
            setLoading(false)
            setUser(userData)
          })
          .catch((error) => {
            setLoading(false)
          });
      } else {
        console.log('user is not logged in')
        setLoading(false)
      }
    });
  }, []);
  
  
  console.log(user)

  if (loading) {
    return (
      <></>
    )
  }

  return (  
    <NavigationContainer>
      <Stack.Navigator>
        { user ? (
          <Stack.Screen name="Home">
            {props => <HomeScreen {...props} extraData={user} />}
          </Stack.Screen>
        ) : (
          <>
            <Stack.Screen name="Login" component={LoginScreen} />
            <Stack.Screen name="Registration" component={RegistrationScreen} />
          </>
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Just to be clear, the first console.log(user) in line no 6 produces a dump of all user variables. The second console.log(user) produces 'undefined'.

That is the expected behavior.

Firebase automatically restores the user credentials from local storage when the app/page reloads. But this requires it to call the server, which takes some time and thus happens asynchronously. While this is going on your main code continues, and your second log shows (correctly) that the current user is still undefined at this point.

Then, when the user credentials are restored, your onAuthStateChanged callback is executed, it sets user and correctly logs the user's properties. And since you call setUser(userData) in there, this will also trigger React to re-render the component, so that it can show the updated user in <HomeScreen {...props} extraData={user} /> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM