Promise Chaining for a Firebase v3 Auth Subsystem - Password Based Users
registerPasswordUser is a weird name. It's sort of like "register a user with a password" which all of registered users should have anyways. registerUser might be just fine.

One thing you can do instead of "nullifying" is to accept a user object that has the 4 fields. Then to "nullify", use Object.assign.

const userDefaults = {email: ..., displayName: ..., password: ..., photoURL: ... };

function registerUser(user){
  const finalUserConfig = Object.assign({}, defaults, user);
  ...
}


There is no way for the caller to actually know if the procedure succeeded or failed. This function is a one-off, and the only way to know is a visual console.log. Consider returning the promise, that way the caller knows it succeeded or failed.

function registerUser(user){
  ...
  return firebase.auth()
    .createUserWithEmailAndPassword(email, password)
    .then(...)
    .then(...)
    .catch(error =&gt; {
      console.log(error.message);

      // promise.catch recovers the chain.
      // We want to preserve the error for the caller.
      return Promise.reject(error);
    })
}


The two thens you have appear to have one-off calls, sendEmailVerification and updateProfile. They first then doesn't return a promise, which means next one doesn't appear to be waiting for it. They both will fire when createUserWithEmailAndPassword resolves and they may both be merged in one then.

However, since they don't return promises, the chain will not know about their presence. Should they fail, your catch will not capture. 

Promise.resolve('test')
.then(function(v){
  Promise.reject('error')
})
.then(function(v){
  console.log('this gets called');
})
.catch(function(error){
  console.log('this never gets called');
});


Consider using Promise.all to handle both calls that return promises. This way, you know if they fail.

Here's how I would do it:

function registerPasswordUser(config){
  const defaults = {email: null,displayName: null,password: null,photoURL: null };
  const userConfig = Object.assign({}, defaults, userConfig);

  firebase.auth()
    .createUserWithEmailAndPassword(userConfig.email, userConfig.password)
    .then(() =&gt; {
      const user = firebase.auth().currentUser;

      // Do both in parallel while being able to capture errors in promise
      return Promise.all([
        user.sendEmailVerification(),
        user.updateProfile({ displayName, photoURL });
      ]);
    })
    .catch(error =&gt; {
      console.log(error.message);
    });
}