2016-10-20 3 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) { 

     } 
    }); 

을 이제는 사용자가 참여하는 각 채팅에 대해 참가자의 아이디가 있습니다.하지만 아이디가 아닌 아이디를 표시하려면 다른 노드에서 데이터를 다시 검색해야합니다. 다른 노드에서 데이터를 검색하기 위해 다른 비동기 listner를 추가해야하기 때문에 여기에 대한 걱정이 있습니다. MySQL과 같은 것이면 문제가되지 않지만 Firebase 리스너는 비동기식입니다. 데이터를 검색하는 비동기식 리스너에 대한이 아이디어는 매우 혼란스럽고 내가 제대로하고 있는지 궁금해합니다. 내가 여기서 뭘해야하지?

+0

언뜻보기에 이것은 클라이언트에서 루핑하여 데이터베이스의 사용자 데이터에 "가입"합니다. 뭐가 문제 야? –

+0

비동기식 리스너를 사용하여 사용자 데이터를 루프 할 때 값이 순서대로 반환된다는 보장이 있습니까? 즉, 첫 번째 수신기가 실행될 때 첫 번째 수신기가 비동기이기 때문에 첫 번째 수신기가 값을 반환했는지 여부에 관계없이 두 번째 수신기가 바로 실행됩니다. 여러 청취자가 비동기 적으로 실행되는지 궁금하네요. 리턴 값이 순차적으로 arraylist에 추가 될 가능성이 있습니까? –

+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) { 

    } 
}); 
관련 문제