1

I'm working on a small app to practice my JAVA/Firebase skills, and I have come into a roadblock. I do admit that I'm not very familiar with Firebase, and rules associated with the database portion. But I have tried looking at other SO posts and searching through documentation.

Problem: Users create an account (through Firebase Authentication - E-mail/Password). Then they are able to create a "character" and provide this "character" with a name. So I need the "charName" to be unique. And obviously the authenticated ID is also unique already. So I need the app to tell users if the name is already taken or if it isn't, then to go ahead with adding it to the database.

Here are simplified snippits of my code:

btnCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String charName = "MyCharactersName";
                final int charID = 123;

                mFirebaseDatabase.child("characters").addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot snapshot) {
                        if (!(snapshot.child(charName).exists())) {

                                Character newCharacter = new Character(charID, charName);

                                mFirebaseDatabase.child("characters").child(getNewCharID()).setValue(newCharacter); // add to database

                                Snackbar.make(findViewById(R.id.view_root), "Success", BaseTransientBottomBar.LENGTH_INDEFINITE).show();
                            } else {
                                Snackbar.make(findViewById(R.id.view_root), "Error creating a character.", BaseTransientBottomBar.LENGTH_INDEFINITE).show();
                            }
                        } else {
                            Snackbar.make(findViewById(R.id.view_root), "That character name is already taken.", BaseTransientBottomBar.LENGTH_INDEFINITE).show();
                        }
                    }
@Override
    public void onCancelled(DatabaseError databaseError) {
                            Snackbar.make(findViewById(R.id.view_root), "Error - Did not connect with Database", BaseTransientBottomBar.LENGTH_INDEFINITE).show();
                    }
                });
            }
        });

Currently: The app creates a new character on the database, but you can add duplicate characters. (the charID is unique by the way, I hardcoded it in the snippit above... but it is timeStamp + 4 random digits).

So that obviously happens with the default database Rules. And in the examples that I did read, it looks like I might have to modify those?

My Database structure is as such:

App / characters / charID / charName

I tried to adapt some code from this SO post: How do you prevent duplicate user properties in Firebase?

and this is what I wrote, but it doesn't work and as I admitted before, I'm not familiar with rules, so I'm not sure what I did/did wrong. haha.

{
  "rules" : {
    "characters" : {
      "$charID" : {
        ".validate": "root.child('charName_lookup/'+newData.val()).val() === auth.uid"
      }
    },
    "charName_lookup" : {
       "$charName" : {
         ".write" : "!data.exists()",
         ".validate": "newData.val() === auth.uid"
        }
      }
  }
}

If you have any questions/clarifications please let me know. I will be stepping away from the computer periodically but I will check back promptly (I hope!)

AL.
  • 36,815
  • 10
  • 142
  • 281

1 Answers1

0

Basically, the userName or the email address should be the name of your node. Regarding rules, you can use wildcards. If you create a userName George, to verify if exists you only need to put a reference on users node and use exists() method.

Please take a look at Frank van Puffelen's explanation from this video. Even if you'll need to remodel a bit your database, remember that this is the best practice when we are talking about duplicates.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Okay. I watched the clip. So basically, I should be taking my value of "charName" and move it up a level! so... App / characters / charName / charID + any other information. All stored under "charName" So my follow up question is regarding rules then. How do I make sure that I'm not rewriting over existing entries? Because I think that's what my first problem was when I was testing things before going this far in depth. So if I have charName = "George" and then click Create Account again with the same name, doesn't it just overwrite the existing "George"? – Jonathon Charles Loch May 25 '17 at 00:00
  • Tested it with the default rules. And it seems to be working. It did NOT let me create a second "George".I'll test it more in depth later when I'm home! Thanks Alex! – Jonathon Charles Loch May 25 '17 at 00:08