2

I understand from the Structuring Data section in the documentation that denormalizing data is useful to achieve more efficient look ups when you have two way relationships.

In my app, I have a denormalized data structure for chats and users:

{
  users: {
      user1: {
          name: "user1",
          chats: {
              chat1: true,
              chat3: true,
          }
      }
      user2: {
          name: "user2",
          chats: {
              chat2: true,
              chat3: true,
          }
      }
  chats: {
      chat1: {
          chatID: "chat1",
          chats: {
              user1: true,
          }
      }
      chat3: {
          chatID: "chat3" ,
          users: {
              user1: true,
              user2: true,
          }
      }
  }
}

I want to query the database for all chats that a particular user is a part of, and load those into a RecyclerView.

Right now, I have a working solution using the FirebaseUI RecyclerViewAdapter in which I set up the FirebaseRecyclerView adapter to query the users/userID/chats reference, and then I set a ValueEventsListener on each chat with key that the adapter finds:

FirebaseRecyclerAdapter<Boolean, ChatViewHolder> adapter = new
            FirebaseRecyclerAdapter<Boolean, ChatViewHolder>(
                    Boolean.class,
                    R.layout.chat_list_item,
                    ChatViewHolder.class,
                    mUserRef.child(mUserID).child("chats")){

                @Override
                protected void populateViewHolder(final ChatViewHolder viewHolder, Boolean model, final int position) {
                    final String key = this.getRef(position).getKey();
                    mChatRef.child(key).addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            Chat chat = dataSnapshot.getValue(Chat.class);
                            viewHolder.bindTo(chat);
                            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Intent chatIntent = new Intent(ChatActivity.this, MessageActivity.class);
                                    chatIntent.putExtra("chatID", key);
                                    startActivity(chatIntent);
                                }
                            });

                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }
            };

This works, but I am afraid of the performance implications since I am adding a new listener to each item independently, rather than a ChildEventListener on a subset of chat items.

Is this the best way to handle this? Thanks in advance for your help.

AL.
  • 36,815
  • 10
  • 142
  • 281
  • Firing a separate request for each item is not a big performance problem on Firebase, since the client pipelines the requests. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786. But you'll have to somewhere also detach those listeners (us use `addSingleValueEventListener()`). – Frank van Puffelen Sep 05 '16 at 16:12
  • Awesome thank you! So this is the way you would get all of the chats that a certain user is part of? It seems like a misuse of the FirebaseRecyclerViewAdapter, since using the Boolean as the model seems a little odd. – Nikita Gamolsky Sep 20 '16 at 22:58

0 Answers0