Adding the displayName whilst using createUserWithEmailAndPassword

18,683

Solution 1

createUserWithEmailAndPassword is an asynchronous call like almost every other function in Firebase. You create the user (most likely successfully) but then immediately after you try and grab the currentUser. In almost every case you will be attempting to get the currentUser before Firebase has finished creating your user.

Rewrite inside callback:

firebase.auth().createUserWithEmailAndPassword(email, password).then(function(user) {
    // [END createwithemail]
    // callSomeFunction(); Optional
    // var user = firebase.auth().currentUser;
    user.updateProfile({
        displayName: username
    }).then(function() {
        // Update successful.
    }, function(error) {
        // An error happened.
    });        
}, function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // [START_EXCLUDE]
    if (errorCode == 'auth/weak-password') {
        alert('The password is too weak.');
    } else {
        console.error(error);
    }
    // [END_EXCLUDE]
});

.then will be called upon success and function(error) will be called upon error. You want to set your user after user creation was successful.

Some people don't like the nested callbacks so you could create a function that gets the current user and call the function upon success.

Docs:

Firebase Promises

Async, callbacks

Solution 2

You have to do like this.

import {AngularFireAuth} from '@angular/fire/auth';
import { auth } from 'firebase';

constructor(private auth: AngularFireAuth) {}

signup(username: string, email: string, password: string) {
  this.auth.auth.createUserWithEmailAndPassword(email, password)
  .then((user: auth.UserCredential) => {
    user.user.updateProfile({
      displayName: username
    });
  })
}

If you use Angular, then you can use dependency injection to inject an AUTH instance to the constructor, then you access to the AUTH service (this.auth.Auth), and create your account with createUserWithEmailAndPassword() method. Once the account is successfully created, it returns Promise< UserCredential >. Since it's wrapped in a Promise you have to use either async, await, or then() to access to the UserCredential typed value. The interface of UserCredential goes as following.

UserCredential: { additionalUserInfo?: AdditionalUserInfo | null; credential: AuthCredential | null; operationType?: string | null; user: User | null }

As you see there are a number of properties in the UserCredential instance, and one of them is USER (user: User | null). This property has all the information of the user. Now you can access to methods of firebase.User. The method responsible for updating the user profile is updateProfile(). It has displayName, PhotoURL properties. Now you can update the userProfile like this. user.user.updateProfile({ displayName: NAME }). Remember you have to update properties inside of parenthesis ( {} ), because updateProfile supports JavaScript object argument. This object has two properties called displayName, and photoURL.

updateProfile ( profile :  { displayName ?: string | null ; photoURL ?: string | null } ) : Promise < void >

https://firebase.google.com/docs/reference/js/firebase.auth.Auth https://firebase.google.com/docs/reference/js/firebase.auth#usercredential https://firebase.google.com/docs/auth/web/password-auth#create_a_password-based_account https://firebase.google.com/docs/reference/js/firebase.User#updateprofile

Share:
18,683

Related videos on Youtube

Admin
Author by

Admin

Updated on June 06, 2022

Comments

  • Admin
    Admin about 2 years

    I want to add the display name to the user that was just created. But when I createUserWithEmailAndPassword it sais my currentUser is null. Anything wrong?

    var name = document.getElementById("name").value;
    var username = document.getElementById("username").value;
    var email = document.getElementById('email').value;
    var password = document.getElementById('password').value;
      // Sign in with email and pass.
      // [START createwithemail]
      firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;
        // [START_EXCLUDE]
        if (errorCode == 'auth/weak-password') {
          alert('The password is too weak.');
        } else {
          console.error(error);
        }
        // [END_EXCLUDE]
      });
      // [END createwithemail]
      var user = firebase.auth().currentUser;
      user.updateProfile({
          displayName: username
        }).then(function() {
          // Update successful.
        }, function(error) {
          // An error happened.
      });
    document.getElementById("submitButton").innerHTML = "Loading...";
    $("#submitButton").css("background-color", "#efefef");
    $("#submitButton").css("cursor", "init");
    $("#submitButton").css("color", "#aaa");
    registerUserToDB(username, name, email);
    console.log("shouldhave worked");
    
  • Admin
    Admin about 8 years
    okay the tip with the .then(function(){...}); was good and works, but the user,updateProfile doesnt... It shows the displayName as null if I run a check on the currentuser and additionally I cannot get the .set function to work for the database.... Any tips?
  • theblindprophet
    theblindprophet about 8 years
    Try my new answer, user is passed into the success callback instead of error and user is used to set the displayName
  • Admin
    Admin about 8 years
    okay, so I tried that and what happens is when alerting that user you get [Object object]... after that the updateProfile function is called... and when I alert the error message this is what it sais: Error: A network error (such as timeout, interrupted connection or unreachable host) has occurred.
  • Mel
    Mel over 4 years
    did you figure this out? I can't get this to work either
  • brewster
    brewster about 4 years
    i believe the promise passes a UserCredential instance, so you need to do .then((userCred) => { userCred.user.updateProfile({...}) })