Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check If Firebase User Exist Without Throwing Error

I have a website that offers a simple messaging service. Individuals can pay for the service, or a business can pay for a monthly subscription and then add their clients/users for free. When the business adds a client/user email, that triggers the function below. I'm using firebase functions and createUser to create the user on my server(less). However, sometimes a business tries to register a user and that user already exist. In this case, I want to send the user a reminder email.

The code I have works fine, but it feels funky having a chain within my catch/error. Is there another way to detect if an email is already registered with a Firebase account that won't throw an error?

exports.newUserRegisteredByBusiness = functions.database.ref('users/{uid}/users/invited/{shortEmail}').onWrite( (data, context) => {

//don't run function if data is null
if (!data.after.val()){
  console.log('SKIP: newUserRegisteredByBusiness null so skipping')
  return null
} else {

  let businessUID = context.params.uid
  let email = data.after.val()
  let shortEmail = context.params.shortEmail
  let password // =  something I randomly generate

  return admin.auth().createUser({ email: email, password: password}).then( (user)=> {

      //write new user data
      let updates = {}
      let userData // = stuff I need for service to run
      updates['users/' + user.uid ] = userData;
      return admin.database().ref().update(updates)
    }).then( () =>{

      //email new user about their new account
      return emailFunctions.newUserRegisteredByBusiness(email, password)

    }).catch( (error) =>{
      //if user already exist we will get error here.
      if (error.code === 'auth/email-already-exists'){
         //email and remind user about account
        return emailFunctions.remindUsersAccountWasCreated(email).then( ()=> {
          //Once email sends, delete the rtbd invite value that triggered this whole function
          //THIS IS WHERE MY CODE FEELS FUNKY! Is it ok to have this chain?
          return admin.database().ref('users/' + businessUID + '/users/invited/' + shortEmail).set(null)
        })
      } else {

        //delete the rtbd value that triggered this whole function
        return admin.database().ref('users/' + businessUID + '/users/invited/' + shortEmail).set(null)

      }


    });

  }
})
like image 998
Will Avatar asked May 03 '18 12:05

Will


People also ask

How do you check if a user has already exists in Firebase authentication?

If you want to check if a user already exists, then you have to save that information either in Firestore or in the Realtime Database, and then simply perform a query to check if a particular phone number already exists. Unfortunately, you cannot check that in the Firebase console.

How do I see total users in Firebase?

There's no built-in method to do get the total user count. You can keep an index of userIds and pull them down and count them. However, that would require downloading all of the data to get a count. Then when downloading the data you can call snapshot.

How do I get Firebase authentication error message?

Each user must have a unique email. The provided Firebase ID token is expired. The Firebase ID token has been revoked. The credential used to initialize the Admin SDK has insufficient permission to access the requested Authentication resource.


2 Answers

To find if a user account was already created for a given email address, you call admin.auth().getUserByEmail.

admin.auth().getUserByEmail(email).then(user => { 
  // User already exists
}).catch(err => { 
  if (err.code === 'auth/user-not-found') {
    // User doesn't exist yet, create it...
  }
})

While you're still using a catch() it feels like a much less failed operation.

like image 151
Frank van Puffelen Avatar answered Sep 28 '22 04:09

Frank van Puffelen


To avoid further implementation in the catch block you can wrap this Firebase function into this code:

async function checkUserInFirebase(email) {
    return new Promise((resolve) => {
        admin.auth().getUserByEmail(email)
            .then((user) => {
                resolve({ isError: false, doesExist: true, user });
            })
            .catch((err) => {
                resolve({ isError: true, err });
            });
    });
}

...

const rFirebase = await checkUserInFirebase('[email protected]');
like image 24
Piotr Sobuś Avatar answered Sep 28 '22 03:09

Piotr Sobuś