0

I have a Vue application that is using Firebase as a backend. New users are registered with email and password option. this is the firebase method:

firebase.auth()
          .createUserWithEmailAndPassword(this.user.email, this.user.password)
          .then((res) => {
            res.user
              .updateProfile({
                displayName: this.user.username,
              })
              .then(() => {
              });
          })
          .catch((error) => {
            this.error = error.message;
            console.log("err", error);
          });

in my main.js file I have onAuthStateChanged method that looks like this:

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    console.log("user", user);
    console.log("nme", user.displayName);
    console.log("email", user.email);
    store.dispatch("fetchUser", user);
  } else {
    store.dispatch("logout");
  }

This method is of course triggered when user is registered. The problem is that I cannot access the displayName property of user, for some reason its always null when user is registered. When I refresh the page, it has value but right after registering its null, and its passing the null value to Vuex, as username. The weird thing is that the email for example can be accessed right away. This is a screenshot from my console:

enter image description here

The first part is the "console.log("user", user) and then there are the other prints. As you can see in the user object, displayName has a value, but when I call user.displayName, its null.

Can someone explain me why this is happening? Thanks in advance!

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
McLovin
  • 91
  • 2
  • 10
  • And if you put a breakpoint in the debugger here, can you get `user.displayName` when you hit the breakpoint? – Kapcash Oct 03 '20 at 14:05

1 Answers1

4

This is because the updateProfile() method is asynchronous and does not trigger the listener set through onAuthStateChanged().

So when the onAuthStateChanged() listener is triggered right after the user is created (and signed in, because after the creation of the user account, the user is also signed in) the value of displayName is not yet updated.

You should probably update the State in your Vuex Store when the promise returned by the updateProfile() method is resolved.

Something along the following lines:

  firebase
    .auth()
    .createUserWithEmailAndPassword(this.user.email, this.user.password)
    .then((res) => {
      return res.user.updateProfile({
        displayName: this.user.username,
      });
    })
    .then(() => {
      //Update the Vuex Store here with firebase.auth().currentUser
      console.log(firebase.auth().currentUser.displayName);
    })
    .catch((error) => {
      this.error = error.message;
      console.log('err', error);
    });
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • I get that its asynchronous, but when I try to display the user object, not just the name, I can clearly see that the property displayName has value and its also in the onAuthStateChanged() method, so how is it possible that I cant access the property value? – McLovin Oct 03 '20 at 16:15
  • The reason is explained in the followong SO answer: https://stackoverflow.com/a/17547032/3371862. If you do `if (user) {console.log(JSON.stringify(user)); ....` you will see that the value of `displayName` is actually `null`. – Renaud Tarnec Oct 03 '20 at 16:43
  • Have also a look at https://areknawo.com/how-to-properly-log-objects-in-javascript/ which explains that it is "due to the value being dynamically-evaluated at the moment of expanding the tree". (i.e. the Object tree displayed in the console) – Renaud Tarnec Oct 03 '20 at 16:55