0

I need a littel help with Firestore. I have a users data collection, user id-documents with each user information. I want to check if username already exists; // "That username already exists". How do I do it?

const signUpForm = document.querySelector('#signup-form'); 
signUpForm.addEventListener('submit', (evt) =>{       
evt.preventDefault();                               
//get user email, password
const email= signUpForm['signup-email'].value;     
const password = signUpForm['signup-password'].value;
const repassword = signUpForm['signup-re-password'].value;

if(password != repassword)
{
    alert("Passwords don't match \nPlease try again");
}
else{  
   if(//check username exist?)
   {
    alert('This username already exist !');
    }
    else { //sign up the user
     auth.createUserWithEmailAndPassword(email, password)
    .then(cred => {
        return db.collection('users').doc(cred.user.uid).set({
            neptun: signUpForm['signup-neptun'].value,
            nickName: signUpForm['signup-nickName'].value
        });                     
      });
   }

});

Update! A working solution :

const username = signUpForm['signup-username'].value; 
db.collection("users").where("username", "==", username).get().then((doc) => {
        if(!doc.empty) {
            alert("This  username is already taken!");
        }
        else{
            //sign up the user               
    });     
FedFAr
  • 9
  • 5

2 Answers2

2

To be straight forward you can just try this code:

const username = ""
const userNameDoc = await firebase.firestore().collection("users").where("username", "==", username).get()
if(!userNameDoc.empty) {
    console.log("This username is already taken!");
}

But as this is all frontend so this can be bypassed if anyone wants to. All this requires you to give all users access to the whole users collection which won't be ideal. So you should ideally use a cloud function or you own server environment for better security.

For example, you can block all direct requests to Firestore collection using security rules and create users using the Admin SDK in cloud functions.

You can use the code below in your cloud function to create a new user by checking if the username is still valid.


exports.createNewUser = functions.https.onCall(async (data, context) => {
  const userEmail = data.email
  const userName = data.name
  const userPass = data.password
  const userNameDoc = await admin.firestore().collection("users").where("username", "==", username).get()
  if(!userNameDoc.empty) {
    console.log("This username is already taken!");
    return {result: "Username is already taken!"}
  } 
  return admin
  .auth()
  .createUser({
    email: 'user@example.com',
    password: userPassword,
    displayName: userName,
  })
  .then((userRecord) => {
    // See the UserRecord reference doc for the contents of userRecord.
    console.log('Successfully created new user:', userRecord.uid);
    return {result: "User Created!"}
  })
  .catch((error) => {
    console.log('Error creating new user:', error);
    return {result: error}
  });
});

The 2nd method is way more secure than first one for your Firestore DB.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
0

Firebase automatically checks if an email is already in use. The createUserWithEmailAndPassword function throws an error, when a user tries to sign up with an email address already in use. Catch errors and then check for the "auth/email-already-in-use" error code:

.catch(function(error){
  if(error.code=="auth/email-already-in-use"){//do something}
})

For more details, see the firebase auth reference https://firebase.google.com/docs/reference/js/firebase.auth.Auth?authuser=1#createuserwithemailandpassword

Nils
  • 61
  • 5