web-dev-qa-db-ja.com

Firebaseデータベースに特定の値が存在するかどうかを確認する

Firebaseリアルタイムデータベースを使用してAndroidアプリケーションを作成しています。新しいユーザーがアプリに登録すると、そのユーザーのデータはFirebaseデータベースに保存されます。

ユーザーは登録するために次の詳細を提供する必要があります。

  1. フルネーム
  2. Eメール
  3. Username
  4. パスワード

データベース構造

enter image description here

新しいユーザーが登録しようとするたびに、各ユーザーのユーザー名が一意であることを確認する必要があるため、ユーザーが入力したusernameがデータベースに既に存在するかどうかを確認します。

これを行うために、次のメソッドを作成しました。

private boolean usernameExists(String username) {
     DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
     return (fdbRefer != null);
}

このメソッドの背後にある私のロジックは、getReferenceメソッドが指定されたパスへの参照を見つけられない場合、nullを返すので、fdbRefernullであるかどうかを返します。 fdbRefernullである場合、usernameがデータベースに存在しないことを意味します。

問題

このメソッドの問題は、入力されたtrueがデータベースに存在するかどうかにかかわらず、常にusernameを返すことです。 fdbRefernullになることはないと信じるようになりました。

これは私の質問に私をもたらします...

質問

getReferenceデータベースで指定されたパスが見つからないときにfirebaseメソッドが返すもの、およびusernameがデータベースに既に存在するかどうかを確認する正しい方法は何ですか?

9
Nick

ユーザーの存在を確認するには、次のコードを使用してください。

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);

クエリを使用して、次のような同じことを実現することもできます。

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users").orderByChild("userName").equalTo("Nick123");
query.addValueEventListener(/* ... */);

これは、Usersノード全体をループする別のアプローチですが、単一のユーザーへの直接参照を使用するだけではありません。このオプションは、ユーザー名の代わりにuidを一意の識別子として使用している場合に使用する可能性が高くなります(現在のように)。したがって、データベース構造が次のようになる場合:

Firebase-root
   |
   --- Users
        |
        --- uid
             |
             --- userName: "Test User"
             |
             --- emailAddress: "[email protected]"

2番目のソリューションが推奨されます。

一意のユーザー名のみを保持できるuserNamesという名前の別のノードを作成する必要がある別のソリューションもあります。以下の対応するセキュリティルールも参照してください。

"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"
    }
  }
}

ただし、この場合、ユーザー名はすでにノードの名前であるため、最初のユーザー名を使用することをお勧めします。

19
Alex Mamo

これを試して:

_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
          }
        }
_

値がある場合は、orderbychildequaltoを使用して値を確認する必要があります。 orderbychildequaltoを使用しない場合、username子ノードが存在するかどうかを確認し、値を気にしません。

このorderByChild("username").equalTo(Nick123)は次のようなものです:

_WHERE username=Nick123
_
2
Peter Haddad

このように確認してください...

    fdbRefer.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exist() {
//username exist
}
else {
//username doesn't exist
}
}
});
2
Amit Joshi

私にぴったり

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        Query query = reference
                .child(getString(R.string.dbname_users))
                .orderByChild("username")
                .equalTo(username);
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.getChildrenCount()>0) {
                    //username found

                }else{
                    // username not found
                }

            }
            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

参照の存在を確認する代わりに、orderByクエリを使用してユーザー名が既に存在するかどうかを確認できます

orderByChild( 'username')。equalTo(username)クエリは、データが既に存在する場合はデータを返しますが、それ以外の場合はnullを返します。

1
sivaram636

あなたはすでにあなたの問題の解決策を持っているので、私はあなたのコードが機能しなかった理由を説明しようとします。

_ DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
_

「Users /」+ usernameがデータベースに存在しない場合、上記のステートメントでfdbReferはnullになると考えているかもしれません。
しかし、実際には、このステートメントはgetReference()の指定されたフィールドへのパスのみを保存します。 _fdbRef!=null_をチェックすると、fdbReferは 'https://.firebase.com/Users/Nick123のような値を保持するため、常にtrueです。

0
vivek kumar