Firebase v3 Offers Authentication via 3rd party oAuth providers, facebook, github,google, and twitter. They also offer password pased authentication.
Authenticated users have a firebase.User object with 4 key properties - displayName, email, photoURL. A password is required to sign in and to register.
In oAuth, the email, displayName, and photoUrl are gotten from the oAuth provider. Developers must enter this in the Firebase v3 Auth system via an .updateProfile
method for Password based users.
So, for registering new users, I collect the 4 values from <inputs>
and call the below homemade function to register the new user with all the values in one go. Promise chaining was used. Any missing arguments must be null
(not undefined
prior to invoking the firebase methods).
Is there a cleaner way to chain these or does this look fairly solid. I know it works. I'm just seeing if it can be smartened up a bit.
createUserWithEmailAndPassword
createUserWithEmailAndPassword(email, password)
returns firebase.Promise
containing non-null firebase.User
. Creates a new user account associated with the specified email address and password.
updateProfile
var profile = {displayName: nullable string, photoURL: nullable string};
updateProfile(profile)
returns firebase.Promise
containing void
. Updates a user's profile data.
function registerPasswordUser(email,displayName,password,photoURL){
var user = null;
//nullify empty arguments
for (var i = 0; i < arguments.length; i++) {
arguments[i] = arguments[i] ? arguments[i] : null;
}
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function () {
user = firebase.auth().currentUser;
user.sendEmailVerification();
})
.then(function () {
user.updateProfile({
displayName: displayName,
photoURL: photoURL
});
})
.catch(function(error) {
console.log(error.message);
});
console.log('Validation link was sent to ' + email + '.');
}
1 Answer 1
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 => {
console.log(error.message);
// promise.catch recovers the chain.
// We want to preserve the error for the caller.
return Promise.reject(error);
})
}
The two then
s 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(() => {
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 => {
console.log(error.message);
});
}
-
\$\begingroup\$ Thanks Joseph. I will try it this way. The reason for the naming of
registerPasswordUser
is that Firebase also has oAuth type users. Password is one of the auth provider names they use. Thanks for looking at this for me. \$\endgroup\$Ronnie Smith– Ronnie Smith2016年07月28日 18:27:31 +00:00Commented Jul 28, 2016 at 18:27