2016-10-20 92 views
0

我正在學習使用Firebase並希望知道我是否正確地進行了操作。如果我理解正確,則只能使用Firebase中的偵聽器異步檢索數據。我會嘗試用一個例子來解釋我的問題。說我有一個簡單的聊天應用程序下面的數據庫中的數據:處理Firebase中的異步偵聽器以檢索數據

chat_info: 
    chatID_1: 
    participants: 
     uId_1: true 
     uId_2: true 

users: 
    uId_1: 
    display_name: "David" 
    participated_chats: 
     chatID_1: true 
     chatID_2: true 
    uId_2: 
    display_name: "Jason" 
    participated_chats: 
     chatID_1: true 
     chatID_2: true 

現在,我想列出大衛參加了聊天記錄,這樣我像做了以下內容:

ArrayList<String> chatIdList = new ArrayList<String>(); 
    // Retrieve chat Ids of participating chats 
    usersRef.child(mFirebaseUser.getUid()).child("participated_chats").addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      chatIdList.clear(); 

      // Save each chat Id to an arraylist 
      for (DataSnapshot child : dataSnapshot.getChildren()) { 
       chatIdList.add(child.getKey()); 

       // when loop hits the last user of the dataSnapsot 
       if(chatIdList.size() >= dataSnapshot.getChildrenCount()) { 

        // For each chat Id, retrieve participants' uIds 
        for(String chatId : chatIdList) { 
         chatInfoRef.child(chatId).addListenerForSingleValueEvent(new ValueEventListener() { 
          @Override 
          public void onDataChange(DataSnapshot dataSnapshot) { 
           Chat chat = dataSnapshot.getValue(Chat.class); // In a Chat class, there is public Map<String, Boolean> participants = new HashMap<>(); 
           chatDetailList.add(chat); 
           chatListAdapter.notifyDataSetChanged(); 
          } 
          @Override 
          public void onCancelled(DatabaseError databaseError) {} 
         }); 

        } 
       } 
      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

現在,我有參與者的用戶參加每次聊天的uIds。但是,由於我想顯示用戶名,而不是uId,我必須再次從另一個節點檢索數據。這是我的擔心,因爲我必須添加另一個異步列表器來從不同節點檢索數據。如果它像MySQL一樣,這不會成爲問題,但Firebase偵聽器是異步的。這種異步偵聽器檢索數據的想法非常混亂,並且奇怪我是否正確地做了這件事。我應該在這裏做什麼?

+0

乍一看,這看起來很好:你在客戶端循環「加入」來自數據庫的用戶數據。有什麼問題? –

+0

當我使用異步偵聽器循環使用用戶數據時,是否保證按順序返回值?換句話說,當第一個偵聽器運行時,第二個偵聽器會立即運行,無論第一個偵聽器是否因爲其任務是異步而返回值。所以我想知道是否多個偵聽器異步運行,是否有可能將返回值無序添加到數組列表? –

+1

所有到數據庫的流量都在同一個套接字上,所以它們都按順序執行。見[這個答案](http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786# 35932786)瞭解更多關於流水線的內容。 –

回答

1

您可以將第一個偵聽器附加到/users/uId_1以獲取整個用戶對象,然後只需從dataSnapshot值中獲取用戶的用戶名/顯示名稱即可。

下面是一個例子。

ArrayList<String> chatIdList = new ArrayList<String>(); 
// Retrieve chat Ids of participating chats 
usersRef.child(mFirebaseUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     chatIdList.clear(); 

     User user = dataSnapshot.getValue(User.class); 
     String username = user.getDisplay_name(); 

     Map<String, Boolean> participated_chats = user.getParticipated_chats(); 
     // Save each chat Id to an arraylist 
     for (Map.Entry<String, Boolean> child : participated_chats.entries()) { 
      chatIdList.add(child.getKey()); 

      // ... continues 
     } 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 

    } 
}); 
相關問題