开发者问题收集

错误是:'TypeError:无法读取属性'uid''但它的定义

2021-08-01
378

我正在创建一个欢迎类型的项目,任何用户都可以使用 react 来迎接那个人

所以我面临的问题是它说:

TypeError: Cannot read property 'uid' of null

但在 firebase 中 uid 是可见的。我已经在控制台上打印了传入的数据,并且 uid 也是可见的,但是在显示内容时整个 UI 崩溃了。

错误是:

  133 | const { username,usermessage,uid,photoURL,usernameByID} = props.messageIN;
  134 | const {isbdaygirl} = props.isBdaygirl;
  135 | console.log(props)
> 136 | const messageType = uid === auth.currentUser.uid ? 'itsmine' : 'others';
      | ^  137 | if(isbdaygirl){
  138 |   return(
  139 |     <div>

我写的代码:

function WishForher(){
  // More Code is there here...
  const sendToDB = async(e) =>{
    e.preventDefault();
    const {uid,photoURL,displayName} = auth.currentUser;
    await msgRef.add({
      username:Username,
      usermessage:wishIN,
      usernameByID:displayName,
      uid,
      createdAt:firebase.firestore.FieldValue.serverTimestamp(),
      photoURL
    })
    console.log(`Your send Data is : \nUserName:${Username}\nUserMessage:${wishIN}`)
    setUsername('');
    setwishIN('');
  }
  const removeAcc = (e) =>{
    auth.signOut()
  }
  return(
    <div>
      <button onClick={()=>setPaswdIn(!paswdIn)}>I am Spoorthi</button>
      {paswdIn && 
        <form onSubmit={isShe}>
          <p>Enter secreat code</p>
          <input 
            type="text" 
            placeholder="Enter..."
            value={enterpaswd}
            onChange={(e)=>{setEnterpaswd(e.target.value)}}/>
          <button type="submit">I Clame</button>
        </form>
      }
      {bdaygirl? <p>Happy Birthday</p>:null}
      {
        messages && messages.map(msg => <Message key={msg.id} messageIN={msg} isBdaygirl={bdaygirl}/>)
      }
      <h2>Wishes</h2>
      <button onClick={wisher}>I wish you ...</button>
      {user && 
        <div>
          <form onSubmit={sendToDB}>
            <p>Your name</p>
            <input 
              type="text" 
              placeholder="Spoorthi recognize you by..."
              value={Username}
              onChange={(e)=>{setUsername(e.target.value)}}/>
            <p>Your name</p>
            <textarea
              type="text" 
              placeholder="I wish you a happy birthday spoorthi..."
              value={wishIN}
              onChange={(e)=>{setwishIN(e.target.value)}}/>
            <button type="submit">Send My Wish</button>
          </form>
        </div>
      }
      <button onClick={removeAcc}>Remove Account</button>
    </div>
  )
}

function Message(props){

  const { username,usermessage,uid,photoURL,usernameByID} = props.messageIN;
  const {isbdaygirl} = props.isBdaygirl;
  console.log(props)
  const messageType = uid === auth.currentUser.uid ? 'itsmine' : 'others';
  if(isbdaygirl){
    return(
      <div>
        <img src={photoURL} alt="ProfilePic"/>
        <h1>{username?username:usernameByID}</h1>
        <p>{usermessage}</p>
      </div>
    )
  }
  else{
    if(messageType==='itsmine'){
      return(
        <div>
          <img src={photoURL} alt="ProfilePic"/>
          <h1>{username?username:usernameByID}</h1>
          <p>{usermessage}</p>
        </div>
      )
    }
    else{
      return(
        <div>
          <img src={photoURL} alt="ProfilePic"/>
          <h1>{username?username:usernameByID}</h1>
          <p>It can be only read by birthday girl for privacy issue</p>
        </div>
      )
    }
  }
}
2个回答

看起来此代码在初始化 auth.currentUser 之前运行。

const messageType = uid === auth.currentUser.uid ? 'itsmine' : 'others'

简单的修复方法是检查该条件:

const messageType = uid === (auth.currentUser && auth.currentUser.uid) ? 'itsmine' : 'others'

这将消除错误并在所有条件下呈现 UI。


为了更好地修复,您需要更改代码,以便它监听(并响应)身份验证状态的变化,这些变化可能随时发生。

为此,您需要使用身份验证状态监听器,如有关 获取当前登录状态的文档中第一个代码片段中所示。用户

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    var uid = user.uid;
    // ...
  } else {
    // User is signed out
    // ...
  }
});

您通常会将此代码包含在功能组件的顶层或构造函数中,然后在 Firebase 恢复用户的身份验证状态或该状态因任何原因发生变化时调用它。

然后,在回调中,您通常会使用 useState 钩子将用户(或从中派生的一些信息)设置为组件的状态。有关此示例,请参阅我的答案: Null 不是对象(评估'firebase.auth().currentUser.email'):FIREBASE REACT NATIVE(EXPO)

Frank van Puffelen
2021-08-01

加载页面时 currentUser 可能为空,最好在 Message 中返回组件之前检查用户是否为空。

尝试在 Message 函数的返回之前添加以下内容:

if (!auth.currentUser) {
    return <div>loading</div>
}
Honghai Mei
2021-08-01