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

     } 
    }); 

Теперь у меня есть участники для каждого чата, в котором участвует пользователь. Но поскольку я хочу отобразить имя пользователя, а не uId, мне нужно снова получить данные из другого узла. Вот мое беспокойство, потому что я должен добавить другого асинхронного списка для извлечения данных с другого узла. Если бы это было что-то вроде 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) { 

    } 
}); 
Смежные вопросы