Sukarna Jana
Sukarna Jana

Reputation: 37

Error is : 'TypeError: Cannot read property 'uid'' but its define

I am creating a greating type project where any user can come and greet that person using react

So the problem which I am facing is that it says:

TypeError: Cannot read property 'uid' of null

But in the firebase uid is visible. I have printed the incoming data at the console, and there also the uid is visible, but when it comes to displaying content the whole UI crash.

Error is:

  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>

Code that i have written :

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>
      )
    }
  }
}

Upvotes: 0

Views: 406

Answers (2)

Honghai Mei
Honghai Mei

Reputation: 81

The currentUser might be null when you load the page, you'd better check if the user is null before you return your component in your Message.

Try add this before the return in your Message function:

if (!auth.currentUser) {
    return <div>loading</div>
}

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 599001

It looks like this code runs before the auth.currentUser is initialized.

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

The simple fix is to check for that condition:

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

This will remove the error and render the UI in all conditions.


For a better fix, you'll want to change your code so it listens to (and responds to) changes in the authentication state, which can happen at any time.

To do this you'll want to use an auth state listener as shown in the first snippet in the documentation on getting the currently signed in user:

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
    // ...
  }
});

You'll typically include this codein the top-level or constructor of your functional component, and it will then be called when Firebase has restored the user's authentication state, or when that state changes for any reason.

In the callback, you'll then typically set the user (or some information derived from that) to the state of your component with a useState hook. For an example of this, see my answer here: Null is not an object (evaluating 'firebase.auth().currentUser.email') : FIREBASE REACT NATIVE (EXPO)

Upvotes: 1

Related Questions