Adding the displayName whilst using createUserWithEmailAndPassword
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
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
For anyone using the new SDK, you could do this the following way in Angular:
import {
...
createUserWithEmailAndPassword,
updateProfile,
} from '@angular/fire/auth';
signup(username: string, email: string, password: string, displayName: string): Promise<void> {
createUserWithEmailAndPassword(this.auth, email, password).then(
userCred => {
updateProfile(userCred.user, { displayName });
}
}