2017-03-04 7 views
2

私はユーザーを保存するデータベースを持っており、新しいものを追加する前にユーザーが存在するかどうかをチェックして上書きしません。新しい値を追加する前にAndroid Studioのfirebaseデータベースが読み込まれるのを待つ

私は、データベースレコードを調べ、ユーザーが見つかった場合や見つからない場合はブール値を返す関数を持っています。

public boolean checkUserExists(final String emailAddress, final String emailDomain){ 
    DatabaseReference myRef = database.getReference("Users"); 

    myRef.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      for (DataSnapshot mydata : dataSnapshot.getChildren()){ 
       User user = mydata.getValue(User.class); 

       if (user.getEmailAddress().equals(emailAddress) && 
         user.getEmailDomain().equals(emailDomain)){ 
        userExists = true; 
        break; 
       } 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

    return userExists; 
} 

私は現在、チェックを行うにしようとしています方法は、このようなものです:

if (!(registerRepo.checkUserExists(emailAddress, emailDomain))){ 
       User user = new User(firsName, lastName, emailAddress, emailDomain); 
       registerRepo.writeUser(user); 
      } else { 
       Toast toast = Toast.makeText(getBaseContext(), "User exists", Toast.LENGTH_SHORT); 
       toast.show(); 
      } 

問題は、それが読み取りのために待機していないということで、先に行くと、新しいレコードを作成します(I pushを使用すると、新しいプッシュIDの下に同じレコードが作成されます)。私はfirebaseがトランザクションハンドラと呼ばれるものを持っているのを見ました。私はそれを使う必要があると思いますが、ドキュメンテーションは私を助けませんでした。私はここで同じ質問をしている人を見ましたが、あなたがそれを行う方法を説明し、他の質問に私をリダイレクトしないと、私は感謝したいと思います。

答えて

1

Firebaseリクエストは非同期です。

データベースから結果を取得した後にコードを実行する場合は、checkUserExistsにコールバックを追加する必要があります。例えば

public interface OnCheckUserExist { 
    void exist(); 
    void notExist(); 
} 

registerRepo.checkUserExists(emailAddress, emailDomain, new OnCheckUserExist(){ 
    @Override 
    public void exist(){ 
     Toast toast = Toast.makeText(getBaseContext(), "User exists",Toast.LENGTH_SHORT); 
     toast.show(); 
    } 
    @Override 
    public void notExist(){ 
     User user = new User(firsName, lastName, emailAddress, emailDomain); 
     registerRepo.writeUser(user); 
    } 
}) 


public void checkUserExists(final String emailAddress, final String emailDomain, OnCheckUserExist onCheckUserExist){ 
    DatabaseReference myRef = database.getReference("Users"); 
    myRef.addValueEventListener(new ValueEventListener() { 
     boolean userExist; 

     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      for (DataSnapshot mydata : dataSnapshot.getChildren()){ 
       User user = mydata.getValue(User.class); 

       if (user.getEmailAddress().equals(emailAddress) && 
         user.getEmailDomain().equals(emailDomain)){ 
        onCheckUserExist.exist(); 
        userExist = true; 
        break; 
       } 
      } 
      if (!userExist){ 
       onCheckUserExist.notExist(); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
} 
+0

そのコールバックは何ですか?私は、通常のasyncTasksがonPostExecuteであることを知っています。それはここで同じですか?どこに追加しますか? –

+0

私の投稿を編集して簡単な例を追加しました – BenjaminBihr

+0

このメソッドを試しましたが、.exist()および.notExist()は静的メソッドではなく、静的コンテンツから参照することはできません。 exist()とnotExist()を静的にすると、 'この言語レベルでは拡張メソッドはサポートされていません'と表示されます。ヘルプ –

0

あなたは、私は別の関数を作成することで、この1をリファクタリングするあなたをお勧めしますが、この

public boolean checkUserExists(final String emailAddress, final String emailDomain){ 
    DatabaseReference myRef = database.getReference("Users"); 

    myRef.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      for (DataSnapshot mydata : dataSnapshot.getChildren()){ 
       User user = mydata.getValue(User.class); 

       if (user.getEmailAddress().equals(emailAddress) && 
         user.getEmailDomain().equals(emailDomain)){ 
        userExists = true; 
        break; 
       } 
      } 
      if (userExists) { 
       User user = new User(firsName, lastName, emailAddress, emailDomain); 
       registerRepo.writeUser(user); 
      } else { 
       Toast toast = Toast.makeText(getBaseContext(), "User exists", Toast.LENGTH_SHORT); 
       toast.show(); 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

    return userExists; 
} 

ようOnDataChangeの内側にあなたのコードを配置する必要があります。 :)

+0

4レイヤーの原則を使用してそれらを分離し、このようにしてデータアクセスレイヤーとアプリケーションロジックレイヤーを組み合わせることを意味します。 –

関連する問題