首页 > 解决方案 > 无法读取 null 的属性(读取 'uid') 为什么它不在屏幕上显示用户 uid?

问题描述

为什么它不在uid屏幕上显示用户?我在 React Native 应用程序中使用电子邮件进行了简单的 firebase 身份验证。一切正常,登录和注册。用户无缝登录 Firebase。但是当我希望它显示用户的 UID 并添加此代码段时,它会显示错误并且应用程序中断:

<Text> Welcome Social Network {user.uid} </Text>

我见过其他同事的例子,它使用相同的代码,但我不理解我的,因为它不适合我

我在互联网上搜索了没有成功的解决方案。我在这个网站上看到了类似的问题,其他问题与我的类似,但不一样,因为正如我所说,这段代码适用于其他人,但不适用于我。如果我删除片段"{user.uid}"一切正常

控制台显示的错误:

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:60)***

这是我的代码:

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

路由.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

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;

我希望这足以让你看到我的错误在哪里。

标签: javascriptreactjsreact-nativefirebase-authentication

解决方案


当页面/应用加载时,Firebase 会尝试从其保留的凭据中恢复之前处于活动状态的用户。这需要它调用服务器,例如检查帐户是否被禁用,这意味着它需要一些时间并且异步发生。

在实践中,这意味着user可能会null在页面加载后的片刻,甚至在此之后将其设置为一个值,您的代码将不得不处理它。

一个简单的方法来做到这一点:

<Text>Welcome Social Network {user ? user.uid : "Loading..."}</Text>

推荐阅读