Je crée une application Android à l'aide de la base de données Firebase
realtime. Lorsqu'un nouvel utilisateur s'enregistre sur mon application, ses données sont enregistrées dans la base de données Firebase.
Un utilisateur doit fournir les informations suivantes pour s'inscrire:
Chaque fois qu'un nouvel utilisateur essaie de s'enregistrer, je dois m'assurer que le nom d'utilisateur de chaque utilisateur est unique afin de vérifier la base de données si la variable username
saisie par l'utilisateur existe déjà dans la base de données ou non.
Pour ce faire, j'ai écrit la méthode suivante:
private boolean usernameExists(String username) {
DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
return (fdbRefer != null);
}
Ma logique derrière cette méthode est que si la méthode getReference
ne peut pas trouver de référence au chemin spécifié, elle renverra null afin que je puisse indiquer si fdbRefer
est null
ou non. Si fdbRefer
est null
, cela signifie que username
n'existe pas dans la base de données.
Le problème avec cette méthode est qu’elle retourne toujours true
que la username
saisie existe ou non dans la base de données. Ce qui m'a amené à croire que fdbRefer
n'est jamais null
.
Cela m'amène à ma question ...
Que renvoie la méthode getReference
quand elle ne trouve pas le chemin spécifié dans la base de données firebase
et quelle est la méthode correcte pour vérifier si la username
existe déjà dans la base de données ou non?
Pour vérifier l'existence d'un utilisateur, veuillez utiliser le code ci-dessous:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("Users").child("Nick123");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
//create new user
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
userNameRef.addListenerForSingleValueEvent(eventListener);
Vous pouvez également utiliser une requête pour obtenir le même résultat:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users").orderByChild("userName").equalTo("Nick123");
query.addValueEventListener(/* ... */);
Il s'agit d'une autre approche qui parcourt l'intégralité du nœud Users
mais n'utilise pas simplement une référence directe à un seul utilisateur. Cette option est plus susceptible d’être utilisée lorsque vous utilisez comme identifiant unique entre utilisateurs la variable uid
au lieu du nom de l’utilisateur (comme vous le faites actuellement). Donc, si votre structure de base de données peut ressembler à ceci:
Firebase-root
|
--- Users
|
--- uid
|
--- userName: "Test User"
|
--- emailAddress: "[email protected]"
La deuxième solution est la recommandée.
Il existe également une autre solution qui implique de créer un autre nœud nommé userNames
, dans lequel vous ne pouvez contenir que les noms d’utilisateur uniques. Veuillez également trouver ci-dessous les règles de sécurité correspondantes:
"Users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.provider === 'password'",
"userName": {
".validate": "
!root.child('userNames').child(newData.val()).exists() ||
root.child('userNames').child(newData.val()).val() == $uid"
}
}
}
Mais puisque dans ce cas, votre nom d'utilisateur est déjà le nom du noeud, je vous recommande d'aller de l'avant avec le premier.
Essaye ça:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Users");
ref.orderByChild("username").equalTo(Nick123).addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
if(dataSnapshot.exist() {
//username exist
}
}
Vous devez utiliser orderbychild
et equalto
pour vérifier la valeur si elle est là . Si vous n'utilisez pas orderbychild
et equalto
, il vérifiera simplement si le noeud enfant username
est présent et ne se soucie pas de la valeur.
this orderByChild("username").equalTo(Nick123)
est comme dire:
WHERE username=Nick123
Vérifiez comme ça ...
fdbRefer.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exist() {
//username exist
}
else {
//username doesn't exist
}
}
});
Au lieu de vérifier l'existence de la référence, vous pouvez utiliser la requête orderBy pour vérifier si le nom d'utilisateur existe déjà.
orderByChild ('username'). equalTo (username) une requête renverrait des données si certaines données existaient déjà, sinon elle renverrait null.
Puisque vous avez déjà une solution à votre problème, je vais essayer d’expliquer pourquoi votre code ne fonctionne pas.
DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
Vous pensez peut-être que, dans la déclaration ci-dessus, la variable fdbRefer
sera nulle si "Utilisateurs /" et le nom d'utilisateur ne sont pas présents dans la base de données.
Mais en réalité, cette instruction ne stockera qu'un chemin d'accès au champ spécifié dans getReference()
. Ainsi, lorsque vous recherchez fdbRef!=null
, il est toujours vrai, car fdbRefer
conservera une valeur comme 'https: //.firebase.com/Users/Nick123.