Why doesn't the user show me uid
on the screen? I have a simple firebase authentication with email in a React Native app. Everything works perfectly, login and registration. The user successfully logs in to Firebase. But when I want it to show me the UID
user's and I add this code snippet, it shows me the error and the app breaks:
<Text> Welcome {user.uid} </Text>
I've seen other peer examples where it does work, using the same code, but I don't understand mine because it doesn't work for me
I have searched the internet for solutions without success. I have seen similar problems, other questions similar to mine on this site, but not the same, because as I say, this code works for other people, but not for me. if I delete the fragment "{user.uid}" everything works perfectly
Error displayed by the console:
TypeError: Cannot read properties of null (reading 'uid')
***This error is located at:
in HomeScreen (at SceneView.tsx:126)
in StaticContainer
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:210)
in RCTView (at View.js:32)
in View (at CardContainer.tsx:280)
in RCTView (at View.js:32)
in View (at CardContainer.tsx:278)
in RCTView (at View.js:32)
in View (at CardSheet.tsx:33)
in CardSheet (at Card.tsx:557)
in RCTView (at View.js:32)
in View (at createAnimatedComponent.js:242)
in AnimatedComponent (at createAnimatedComponent.js:295)
in AnimatedComponentWrapper (at Card.tsx:536)
in PanGestureHandler (at GestureHandlerNative.tsx:14)
in PanGestureHandler (at Card.tsx:530)
in RCTView (at View.js:32)
in View (at createAnimatedComponent.js:242)
in AnimatedComponent (at createAnimatedComponent.js:295)
in AnimatedComponentWrapper (at Card.tsx:526)
in RCTView (at View.js:32)
in View (at Card.tsx:520)
in Card (at CardContainer.tsx:218)
in CardContainer (at CardStack.tsx:649)
in RNSScreen (at createAnimatedComponent.js:242)
in AnimatedComponent (at createAnimatedComponent.js:295)
in AnimatedComponentWrapper (at src/index.native.tsx:171)
in Screen (at Screens.tsx:37)
in MaybeScreen (at CardStack.tsx:642)
in RNSScreenContainer (at src/index.native.tsx:238)
in ScreenContainer (at Screens.tsx:20)
in MaybeScreenContainer (at CardStack.tsx:561)
in RCTView (at View.js:32)
in View (at Background.tsx:13)
in Background (at CardStack.tsx:559)
in CardStack (at StackView.tsx:437)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (at SafeAreaProviderCompat.tsx:46)
in SafeAreaProviderCompat (at StackView.tsx:430)
in RCTView (at View.js:32)
in View (at StackView.tsx:429)
in StackView (at createStackNavigator.tsx:118)
in Unknown (at createStackNavigator.tsx:117)
in StackNavigator (at AppStack.js:9)
in AppStack (at Routes.js:28)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:430)
in BaseNavigationContainer (at NavigationContainer.tsx:132)
in ThemeProvider (at NavigationContainer.tsx:131)
in NavigationContainerInner (at Routes.js:27)
in Routes (at navigation/index.js:9)
in AuthProvider (at navigation/index.js:8)
in Providers (at App.js:5)
in App (at renderApplication.js:50)
in RCTView (at View.js:32)
in View (at AppContainer.js:92)
in RCTView (at View.js:32)
in View (at AppContainer.js:119)
in AppContainer (at renderApplication.js:43)
in pinkilinkyApp(RootComponent) (at renderApplication.js:600***
Here is my code:
HomeScreen.js
import React, { useContext } from "react"
import { View, Text, StyleSheet } from "react-native"
import auth from '@react-native-firebase/auth'
import FormButton from "../components/FormButton"
import { AuthContext } from "../navigation/AuthProvider"
import globalStyles from "../styles/global"
const HomeScreen = () => {
const { user, logout } = useContext(AuthContext)
return (
<View style={globalStyles.containerHome}>
<Text style={globalStyles.textHome}>Welcome {user.uid} </Text>
<FormButton buttonTitle="Logout" onPress={() => logout()} />
</View>
)
}
export default HomeScreen
routes.js
import React, { useContext, useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native'
import auth from '@react-native-firebase/auth'
import { AuthContext } from './AuthProvider'
import AuthStack from './AuthStack'
import AppStack from './AppStack'
const Routes = () => {
const [initializing, setInitializing] = useState(true)
const [user, setUser] = useState()
const onAuthStateChanged = (user) => {
setUser(user)
if (initializing) setInitializing(false)
}
useEffect(() => {
const subscriber = auth().onAuthStateChanged(onAuthStateChanged)
return subscriber // unsubscribe on unmount
}, [])
if (initializing) return null// podemos usar un cargador mientras carga firebase
return (
<NavigationContainer>
{ user ? <AppStack/> : <AuthStack/> }
</NavigationContainer>
)
}
export default Routes
index.js
import React from "react"
import { AuthProvider } from './AuthProvider'
import Routes from "./Routes"
const Providers = () => {
return (
<AuthProvider>
<Routes />
</AuthProvider>
)
}
export default Providers
AuthProvider.js
import React, { createContext, useState } from "react";
import auth from "@react-native-firebase/auth";
export const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
return (
<AuthContext.Provider
value={{
user,
setUser,
login: async (email, password) => {
try {
await auth().signInWithEmailAndPassword(email, password);
} catch (e) {
console.log(e);
}
},
register: async (email, password) => {
try {
await auth().createUserWithEmailAndPassword(email, password);
} catch (e) {
console.log(e);
}
},
logout: async () => {
try {
await auth().signOut();
} catch (e) {
console.log(e);
}
}
}}
>
{children}
</AuthContext.Provider>
);
};
export default AuthProvider
From what I see, the
useState
one you use to get the credentials fromauth().onAuthStateChanged(...)
is different from the contextAuthContext
you use to get the data in the home. Finally allowing if it is rendered<AppStack/>
but with the value ofuser
in the context asnull
.Try changing the Routes.js like so:
Even if it were this, it seems strange to me that the same code works for others with the same credentials. There must be another problem there that I don't think I can solve with the code you show.
can you try this?
According to Firebase, this is the correct method of storing the user:
The problem is because user starts at null when declaring the state
And when making the request it takes time to respond; Two things can happen: 1.- That the request is not responding with the users 2.- That the request is late and when trying to read the user object, since it is null, that message appears Try this
And then do a console.log(user) and check that it's coming through as you expect.