2017-03-04 62 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(); 
      } 

的問題是,它不會等待讀取和前進並創造新的記錄(我使用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()是非靜態方法,它們不能從靜態內容中引用。如果我使存在()和notExist()靜態,它表示'在此語言級別不支持擴展方法'。請幫助 –

0

你需要把你的代碼中onDataChange這樣

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

雖然我會建議你重構這個一個通過創建獨立的功能。 :)

+0

我希望使用4層原則將它們分開,並以這種方式進行分離,這意味着將數據訪問層與應用程序邏輯層結合在一起。 –

相關問題