1

I have a function (not finished yet) that should check if a username already exists/is unique in my Firebase database. I have searched Google on how to implement this and I have managed to get the below. Unfortunately, it doesn't work and I don't even get any console.logs. Any help is appreciated - what exactly am I doing wrong?

 onChangeUsername = (event) => {

var oldError = {...this.state.error};

firebase.database().ref().child("Usernames").orderByValue().once('value', (snapshot) => {
  var exists = (snapshot.val() !== null);
  console.log(exists);
  console.log("hello");
});


if(this.state.validation.username.unique===true)
{oldError.username = "This username is already taken"}

else if((event.nativeEvent.text.length<this.state.validation.username.min) || (event.nativeEvent.text.length>this.state.validation.username.max) )
{oldError.username = "Username should be between " + this.state.validation.username.min + " and " + this.state.validation.username.max + " characters" ;}


else oldError.username = "";



this.setState({ username: event.nativeEvent.text, error:oldError })
}

my database structure is as follows:

Database:{ Usernames: {uid1: username1, uid2: username2}}

****Question Update **** After Comments from Frank, I have changed my code to the following. It still doesn't work, but my he has spotted a couple of errors that needed fixing:

onChangeUsername = (event) => {

    var oldError = {...this.state.error};

    firebase.database().ref().child("Usernames").orderByKey().equalTo("Username1").once('value', (snapshot) => {
      var exists = (snapshot.val() !== null);
      console.log(exists);
      console.log("hello");
    });


    if(this.state.validation.username.unique===true)
    {oldError.username = "This username is already taken"}

    else if((event.nativeEvent.text.length<this.state.validation.username.min) || (event.nativeEvent.text.length>this.state.validation.username.max) )
    {oldError.username = "Username should be between " + this.state.validation.username.min + " and " + this.state.validation.username.max + " characters" ;}


    else oldError.username = "";



    this.setState({ username: event.nativeEvent.text, error:oldError })
  }

and my database to the following:

Database:{ Usernames: {Username1: uid1, Username2: uid2}}
NoobTW
  • 2,466
  • 2
  • 24
  • 42
HarryShotta
  • 347
  • 1
  • 15

1 Answers1

6

You're missing a comparison in your query:

firebase.database().ref().child("Usernames").equalTo("Username1").orderByValue()

I recommend btw inverting the data structure. If you want user names to be unique, use those as the keys in the parent node:

Database:{ 
  Usernames: {
    Username1: uidOfUserWithUsername1, 
    Username2: uidOfUserWithUsername2 
  }
}

This way your lookups will be simpler and fast, since you don't need a query. In addition, the value will now allow you to easily look up more information on the user who claimed this user name.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I already had equalTo("Username1") in there, but must have deleted it when trying new things along the way. Adding the equalTo doesn't change anything for me. I will invert my database as suggested though. – HarryShotta Aug 22 '19 at 21:17
  • Don't update your question to mismatch with existing responses please. Feel free to make edits, but make sure that existing responses (comments, answers) stay valid. Otherwise future readers will have no idea how to make sense of this page. – Frank van Puffelen Aug 22 '19 at 21:29
  • Note that "doesn't change anything" is very unlikely since the code is different. It would be good at this point to know exactly what line isn't doing what you expect when you step through the code in a debugger. – Frank van Puffelen Aug 22 '19 at 21:30
  • Thanks for your comments Frank. So in terms of output, neither of the console logs output anything, i.e. it's not getting to those lines. The function is called however. I will try to clear up this question so it makes sense for future readers also. – HarryShotta Aug 22 '19 at 21:32
  • 1
    You might want to add a `catch` to the `once`, to see if there's a (security) error in that case. If you have a connection to the database, either the `then()` or the `catch()` of a `once()` should always be called. – Frank van Puffelen Aug 22 '19 at 23:24
  • Yes, my rules in Firebase were incorrect. No security errors showed until I caught them. – HarryShotta Aug 23 '19 at 09:47