TypeError:无法读取 null 的属性“uid”

Posted

技术标签:

【中文标题】TypeError:无法读取 null 的属性“uid”【英文标题】:TypeError: Cannot read property 'uid' of null 【发布时间】:2019-02-14 16:40:24 【问题描述】:

我正在尝试使用 Firebase 应用中的电话号码登录,但我在登录过程中遇到问题。我无法在 firebase 中使用电话号码登录,但如果我使用电话号码注册并重定向到主页,它就可以正常工作。我使用相同的方法登录,但我遇到了TypeError: Cannot read property 'uid' of null 之类的问题,但我成功获取了所有控制台值。我不知道这里有什么问题。但是那个错误重复显示3次,

这是我的代码:

    renderLoginButton() 
        if (this.props.loading) 
          return (
            <Spinner size="large" />
          );
        

        return (
          <Button
          style= alignSelf: 'flex-start' 
            onPress=this.onLoginBtnClicked.bind(this)
          >
            Login
          </Button>
        );
      

onLoginBtnClicked()

    const  contact, password  = this.props;
    const error =  Validator('password', password) ||  Validator('contact', contact);

    if (error !== null) 
      Alert.alert(error);
     else 
          console.log('else');
        // this.props.loginUser( contact, password);

        const mobileNo = '+91'+contact;
        firebase.auth().signInWithPhoneNumber(mobileNo)
        .then(confirmResult =>
            console.log(confirmResult),
            curr = firebase.auth(),
            console.log("curr"+JSON.stringify(curr)),
            this.setState( data: curr),
            NavigationService.navigate('Home')
        )
        .catch(error => console(error.message) );
    


CustomDrawerComponent.js

    import React,  Component  from 'react';
import  View, Image, Text  from 'react-native';
import  DrawerItems  from 'react-navigation';
import  connect  from 'react-redux';

import  fetchUserDetails  from '../actions';

class CustomDrawerContentComponent extends Component 

  state = 
    uri: '',
    isfailed: ''
  

  componentWillMount() 
    this.props.fetchUserDetails();
  

  componentWillReceiveProps(nextProps) 
    let uri = '';
    if (nextProps.ProfilePic !== '') 
      uri = nextProps.ProfilePic;
      this.setState( uri, isfailed: false );
     else 
      uri = '../images/ic_person_24px.png';
      this.setState( uri, isfailed: true );
    

    this.setState( uri );
  

  renderProfileImage() 
    if (!this.state.isfailed) 
      return (
        <Image
          style=styles.profileImageStyle
          source= uri: (this.state.uri) 
        />
      );
    
    return (
      <Image
        style=styles.profileImageStyle
        source=require('../images/ic_person_24px.png')
      />
    );
  

  render() 
    console.log('Profile Pic :: ', this.props.ProfilePic);
    return (
      <View style=styles.container>
        this.renderProfileImage()
        <Text style=styles.textStyle>
          this.props.name - this.props.category
        </Text>
        <DrawerItems ...this.props />
      </View>
    );
  


const styles = 
  container: 
    flex: 1,
    paddingLeft: 10
  ,
  textStyle: 
    fontSize: 14,
    textAlign: 'left',
    color: '#000000'
  ,
  profileImageStyle: 
    alignSelf: 'flex-start',
    marginTop: 16,
    padding: 10,
    width: 40,
    height: 40,
    borderRadius: 75
  
;

const mapStateToProps = state => 
  const  userprofile  = state;
  return userprofile;
;

export default connect(mapStateToProps,  fetchUserDetails )(CustomDrawerContentComponent);

调用栈:

【问题讨论】:

您需要发布CustomDrawerComponent 的代码,在这里您使用uid 或示例代码库来重现问题。 代码已更新,请检查并将我吸引到问题 uid 似乎没有出现在这里,您能否分享一个示例代码库来重现问题以彻底检查是否可能? 是的,这就是为什么我想知道为什么会产生这个错误 【参考方案1】:

为什么user 返回为undefined(甚至null)?

你知道有一个登录用户,你刚刚登录,哎呀,你甚至可以在 chrome 开发工具中看到用户对象。

那为什么它仍然返回未定义?有一个直接的答案。

您正在获取用户对象之前该对象已准备好使用。

现在,这可能由于多种不同的原因而发生,但如果您遵循这 2 条“规则”,您将不会再看到该错误。

规则 #1:将其移出constructor()

当你有类似的东西时:

constructor()
  this.userId = firebase.auth().currentUser.uid

超过一半的页面加载时间,构造函数会在用户准备好之前尝试获取用户,应用程序会阻止它,因为页面没有完全加载,所以你会尝试访问尚不存在的属性的 uid。

当您的页面完全加载后,您现在可以调用以获取currentUser.uid

规则 #2:使其成为 Observable

您可以采用另一种方法,即我们刚刚进行的先前 Firebase 调用:firebase.auth().currentUser 是同步的。我们可以通过订阅 auth observable 来使其异步。

/**
   * When the App component mounts, we listen for any authentication
   * state changes in Firebase.
   * Once subscribed, the 'user' parameter will either be null 
   * (logged out) or an Object (logged in)
   */
  componentDidMount() 
    this.authSubscription = firebase.auth().onAuthStateChanged((user) => 
      this.setState(
        loading: false,
        user,
      );
    );
  
  /**
   * Don't forget to stop listening for authentication state changes
   * when the component unmounts.
   */
  componentWillUnmount() 
    this.authSubscription();
  
  render() 
    // The application is initialising
    if (this.state.loading) return null;
    // The user is an Object, so they're logged in
    if (this.state.user) return <LoggedIn />;
    // The user is null, so they're logged out
    return <LoggedOut />;
  

来源文章:Why does Firebase return undefined when fetching the uid?

一个很好的 React Native 教程将在这里:Getting started with Firebase Authentication on React Native 由于您的代码没有显示太多,我希望您对您的问题进行更新以显示更多代码,以便我可以查看。

【讨论】:

非常感谢您的回复,但我已经尝试过这个对我不起作用的解决方案,因为我在这个社区上传代码有限制,我无法在这里显示整个代码 @MahiParmar 或者你可以在这里找到它medium.com/react-native-training/… 再次感谢分享知识,但我唯一的要求是仅使用电话号码而不是电子邮件登录。 我知道,但您的主要问题是您的代码没有获得授权信息,这可能是由于您的应用在获得授权之前加载到其他事件。因此,您只需要调整您的代码样式。 :) 您现在的场景就像您正在乘坐公共汽车(您的应用程序),您在终点站支付了巴士票(登录)但您忘记从柜台取票(没有从身份验证中获取响应)并立即上车(登录后的下一个活动/事件)。上车后,公交车司机要你的票,你发现你没有带票(uid = null)。

以上是关于TypeError:无法读取 null 的属性“uid”的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法读取 null 的属性(读取“classList”)

TypeError:无法读取 null 的属性(读取“1”)

TypeError:无法读取 null 的属性“userID”

TypeError:无法读取 null 的属性(读取“classList”)反应

TypeError:无法读取 null 的属性“uid”

× TypeError: 无法读取 null 的属性“名称”