title: Data inside RecyclerView is getting populated twice using Socket.IO
body: <p>I am working on chat application which uses Socket.IO for sending and receiving messages.Problem which i am facing is when a user send a message to other user,its message gets populated twice inside recyclerview.</p>
  
  <p>My Fragment code :- </p>
  
  <pre><code>public class ChatFragment extends Fragment {
  
  
      private static final String TAG = "MainFragment";
  
      private static final int REQUEST_LOGIN = 0;
  
      private static final int TYPING_TIMER_LENGTH = 600;
  
      private RecyclerView mMessagesView;
      private EditText mInputMessageView;
      private ArrayList&lt;Message&gt; mMessages = new ArrayList&lt;Message&gt;();
      private RecyclerView.Adapter mAdapter;
      private boolean mTyping = false;
      private Handler mTypingHandler = new Handler();
      private String mUsername = "";
      private Socket mSocket;
      String myId ="abc";
      String friendId = "xyz";
  
      private Boolean isConnected = true;
  
      public ChatFragment() {
          super();
      }
  
  
  
      boolean isUser1 = false; // make false for user 2
  
  
      @Override
      public void onAttach(Context context) {
          super.onAttach(context);
          mAdapter = new MessageAdapter(mMessages, context);
          if (context instanceof Activity) {
  
          }
      }
  
  
      public String getSendMessageString(String message) {
          try {
  
              JSONObject jsonObject = new JSONObject();
              if (isUser1) {////User 1
                  jsonObject.put("from", myId);
                  jsonObject.put("to", friendId);
              } else {
                  jsonObject.put("to", friendId);
                  jsonObject.put("from", myId);
              }
              jsonObject.put("room", "vamediabox");
              jsonObject.put("username", mUsername);
              jsonObject.put("messageType", "1"); //1: text message 2: multimedia message
              jsonObject.put("msg", message);
              jsonObject.put("page", 1);
              return jsonObject.toString();
          } catch (Exception e) {
              e.printStackTrace();
          }
          return message;
      }
  
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          setHasOptionsMenu(true);
          mUsername = isUser1? "Himanshu" : "Danish";
          ChatApplication app = (ChatApplication) getActivity().getApplication();
          mSocket = app.getSocket();
          mSocket.on(Socket.EVENT_CONNECT, onConnect);
          mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
          mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
          mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
          mSocket.on("new message", onNewMessage);
          mSocket.on("user joined", onUserJoined);
          mSocket.on("user left", onUserLeft);
          mSocket.on("typing", onTyping);
          mSocket.on("stop typing", onStopTyping);
          mSocket.connect();
  
  //        startSignIn();
      }
  
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                               Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_chat, container, false);
      }
  
      @Override
      public void onDestroy() {
          super.onDestroy();
  
          mSocket.disconnect();
  
          mSocket.off(Socket.EVENT_CONNECT, onConnect);
          mSocket.off(Socket.EVENT_DISCONNECT, onDisconnect);
          mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
          mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
          mSocket.off("new message", onNewMessage);
          mSocket.off("user joined", onUserJoined);
          mSocket.off("user left", onUserLeft);
          mSocket.off("typing", onTyping);
          mSocket.off("stop typing", onStopTyping);
      }
  
      @Override
      public void onViewCreated(View view, Bundle savedInstanceState) {
          super.onViewCreated(view, savedInstanceState);
  
          mMessagesView = (RecyclerView) view.findViewById(R.id.rv_messages);
          mMessagesView.setLayoutManager(new LinearLayoutManager(getActivity()));
          mMessagesView.setAdapter(mAdapter);
  
          mInputMessageView = (EditText) view.findViewById(R.id.et_message);
          mInputMessageView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
              @Override
              public boolean onEditorAction(TextView v, int id, KeyEvent event) {
                  if (id == R.id.send || id == EditorInfo.IME_NULL) {
                      attemptSend();
                      return true;
                  }
                  return false;
              }
          });
          mInputMessageView.addTextChangedListener(new TextWatcher() {
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
              }
  
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  if (null == mUsername) return;
                  if (!mSocket.connected()) return;
  
                  if (!mTyping) {
                      mTyping = true;
                      mSocket.emit("typing", getSendMessageString(""));
                  }
  
                  mTypingHandler.removeCallbacks(onTypingTimeout);
                  mTypingHandler.postDelayed(onTypingTimeout, TYPING_TIMER_LENGTH);
              }
  
              @Override
              public void afterTextChanged(Editable s) {
              }
          });
  
          Button sendButton = (Button) view.findViewById(R.id.btn_send);
          sendButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  attemptSend();
              }
          });
      }
  
  
      private void addLog(String message) {
          mMessages.add(new Message.Builder(Message.TYPE_LOG)
                  .message(message).build());
          mAdapter.notifyItemInserted(mMessages.size() - 1);
          scrollToBottom();
      }
  
      private void addParticipantsLog(int numUsers) {
          addLog(getResources().getQuantityString(R.plurals.message_participants, numUsers, numUsers));
      }
  
      private void addMessage(String username, String message , String sender) {
  
  
          if(myId == sender){
  
  
              mMessages.add(new Message.Builder(Message.SENDER)
                      .username(username).message(message).userId(sender).build());
              mAdapter.notifyItemInserted(mMessages.size() - 1);
              scrollToBottom();
  
          }else{
  
  
              mMessages.add(new Message.Builder(Message.RECEIVER)
                      .username(username).message(message).userId(sender).build());
              mAdapter.notifyItemInserted(mMessages.size() - 1);
              scrollToBottom();
  
          }
  
  
      }
  
      private void addTyping(String username) {
          mMessages.add(new Message.Builder(Message.TYPE_ACTION)
                  .username(username).build());
          mAdapter.notifyItemInserted(mMessages.size() - 1);
          scrollToBottom();
      }
  
      private void removeTyping(String username) {
          for (int i = mMessages.size() - 1; i &gt;= 0; i--) {
              Message message = mMessages.get(i);
              if (message.getType() == Message.TYPE_ACTION &amp;&amp; message.getUsername().equals(username)) {
                  mMessages.remove(i);
                  mAdapter.notifyItemRemoved(i);
              }
          }
      }
  
      private void attemptSend() {
          if (null == mUsername) return;
          if (!mSocket.connected()) return;
  
          mTyping = false;
  
          String message = mInputMessageView.getText().toString().trim();
          if (TextUtils.isEmpty(message)) {
              mInputMessageView.requestFocus();
              return;
          }
  
          mInputMessageView.setText("");
          addMessage(mUsername, message,myId);
  
          // perform the sending message attempt.
          mSocket.emit("new message", getSendMessageString(message));
      }
  
  
  
      private void leave() {
          mUsername = null;
          mSocket.disconnect();
          mSocket.connect();
  //        startSignIn();
      }
  
      private void scrollToBottom() {
          mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
      }
  
      private Emitter.Listener onConnect = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      if (!isConnected) {
                          if (null != mUsername)
                              mSocket.emit("add user", getSendMessageString(""));
                          mSocket.emit("messages by page no", getSendMessageString(""));
                          Toast.makeText(getActivity().getApplicationContext(),
                                  R.string.connect, Toast.LENGTH_LONG).show();
                          isConnected = true;
                      }
                  }
              });
          }
      };
  
      private Emitter.Listener onDisconnect = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      Log.i(TAG, "diconnected");
                      isConnected = false;
                      Toast.makeText(getActivity().getApplicationContext(),
                              R.string.disconnect, Toast.LENGTH_LONG).show();
                  }
              });
          }
      };
  
      private Emitter.Listener onConnectError = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      Log.e(TAG, "Error connecting");
                      Toast.makeText(getActivity().getApplicationContext(),
                              R.string.error_connect, Toast.LENGTH_LONG).show();
                  }
              });
          }
      };
  
      private Emitter.Listener onNewMessage = new Emitter.Listener() {
          @Override
          public void call(final Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      JSONObject data = (JSONObject) args[0];
                      String username;
                      String message;
                      String sender;
                      try {
                          username = data.getString("username");
                          message = data.getString("message");
                          sender = data.getString("sender");
  
                      } catch (JSONException e) {
                          Log.e(TAG, e.getMessage());
                          return;
                      }
  
                      removeTyping(username);
                      if (myId == sender){
  
  
  
                      }else{
  
  
                          addMessage(username,message,sender);
                      }
  
  
                  }
              });
          }
      };
  
      private Emitter.Listener onUserJoined = new Emitter.Listener() {
          @Override
          public void call(final Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      JSONObject data = (JSONObject) args[0];
                      String username;
                      int numUsers;
                      try {
                          username = data.getString("username");
                          numUsers = data.getInt("numUsers");
                      } catch (JSONException e) {
                          Log.e(TAG, e.getMessage());
                          return;
                      }
  
                      addLog(getResources().getString(R.string.message_user_joined, username));
                      addParticipantsLog(numUsers);
                  }
              });
          }
      };
  
      private Emitter.Listener onUserLeft = new Emitter.Listener() {
          @Override
          public void call(final Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      JSONObject data = (JSONObject) args[0];
                      String username;
                      int numUsers;
                      try {
                          username = data.getString("username");
                          numUsers = data.getInt("numUsers");
                      } catch (JSONException e) {
                          Log.e(TAG, e.getMessage());
                          return;
                      }
  
                      addLog(getResources().getString(R.string.message_user_left, username));
                      addParticipantsLog(numUsers);
                      removeTyping(username);
                  }
              });
          }
      };
  
      private Emitter.Listener onTyping = new Emitter.Listener() {
          @Override
          public void call(final Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      JSONObject data = (JSONObject) args[0];
                      String username;
                      try {
                          username = data.getString("username");
                      } catch (JSONException e) {
                          Log.e(TAG, e.getMessage());
                          return;
                      }
                      addTyping(username);
                  }
              });
          }
      };
  
      private Emitter.Listener onStopTyping = new Emitter.Listener() {
          @Override
          public void call(final Object... args) {
              getActivity().runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      JSONObject data = (JSONObject) args[0];
                      String username;
                      try {
                          username = data.getString("username");
                      } catch (JSONException e) {
                          Log.e(TAG, e.getMessage());
                          return;
                      }
                      removeTyping(username);
                  }
              });
          }
      };
  
  
      private Runnable onTypingTimeout = new Runnable() {
          @Override
          public void run() {
              if (!mTyping) return;
  
              mTyping = false;
              mSocket.emit("stop typing", getSendMessageString(""));
          }
      };
  }
  </code></pre>
  
  <p>My Adapter Class which i am using to inflate the layouts for the sent and received messages. </p>
  
  <pre><code>public class MessageAdapter extends RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt; {
  
      ArrayList&lt;Message&gt; arrayList;
      Context context;
      private int SENDER = Message.SENDER;
      private int RECEIVER = Message.RECEIVER;
      private final int TYPE_LOG = Message.TYPE_LOG;
      private final int TYPE_ACTION = Message.TYPE_ACTION;
  
  
  
      public MessageAdapter(ArrayList&lt;Message&gt; arrayList, Context context) {
          this.arrayList = arrayList;
          this.context = context;
  
  
      }
  
  
  
      @Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  
          View v = null;
          RecyclerView.ViewHolder vh = null;
          if (viewType == TYPE_LOG || viewType == TYPE_ACTION)
          {
              v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_log, parent, false);
              vh = new LogMessageHolder(v);
  
          }  else {
  
              if (viewType == SENDER) {
  
                  v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false);
                  vh = new SenderMessageHolder(v);
              }else{
  
                  v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message1, parent, false);
                  vh = new ReceiverMessageHolder(v); }
  
          }
  
          return vh;
  
  
      }
  
      @Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  
  
          Calendar currnetDateTime = Calendar.getInstance();
          SimpleDateFormat df = new SimpleDateFormat("HH:mm a");
          String currentTime = df.format(currnetDateTime.getTime());
  
  
          if (holder.getItemViewType() == TYPE_LOG || holder.getItemViewType() == TYPE_LOG) {
  
              ((LogMessageHolder) holder).log_msg.setText(arrayList.get(position).getMessage());
          }
          else {
  
  
              if (holder.getItemViewType() == SENDER) {
                  ((SenderMessageHolder) holder).txt_send_msg.setText(arrayList.get(position).getMessage());
                  ((SenderMessageHolder) holder).send_time.setText(currentTime);
              } else
              {
  //                (holder.getItemViewType() == RECEIVER){
                  ((ReceiverMessageHolder) holder).txt_recei_msg.setText(arrayList.get(position).getMessage());
                  ((ReceiverMessageHolder) holder).recei_time.setText(currentTime);
  
              }
          }
  
      }
  
  
  
  
  
  
  
      @Override
      public int getItemCount() {
          return arrayList == null ? 0 : arrayList.size();
      }
  
  
      @Override
      public long getItemId(int position) {
          return position;
      }
  
  
      @Override
      public int getItemViewType(int position) {
  
          if(arrayList.get(position).getType() == TYPE_LOG  || arrayList.get(position).getType() == TYPE_ACTION ){
  
              return TYPE_LOG;
          }
          else {
  
              if (arrayList.get(position).getType() == SENDER){
                  return SENDER;
              }
              else {
  
                  return RECEIVER;
  
              }
          }
  
  
      }
  
  
  
  
      private class SenderMessageHolder extends RecyclerView.ViewHolder {
          TextView txt_send_msg, send_time;
  
  
          public SenderMessageHolder(View itemView) {
              super(itemView);
              txt_send_msg = (TextView) itemView.findViewById(R.id.txt_sender_msg);
              send_time = (TextView) itemView.findViewById(R.id.txt_sender_time);
  
  
  
          }
      }
  
      private class ReceiverMessageHolder extends RecyclerView.ViewHolder {
  
          TextView txt_recei_msg, recei_time;
  
          public ReceiverMessageHolder(View itemView) {
              super(itemView);
  
              txt_recei_msg = (TextView) itemView.findViewById(R.id.txt_recei_msg);
              recei_time = (TextView) itemView.findViewById(R.id.txt_recei_time);
          }
      }
  
  
  
      private class LogMessageHolder extends RecyclerView.ViewHolder {
  
          TextView log_msg;
  
          public LogMessageHolder(View itemView) {
              super(itemView);
  
              log_msg= (TextView) itemView.findViewById(R.id.message);
  
          }
      }
  
  }
  </code></pre>
  
  <p>I am not able to figure out why the same message is getting populated for the sender that too from the left side which is actually meant for received messages only.</p>
  
  <p>Here is the screenshot of the chat window.<a href="https://i.stack.imgur.com/FigkW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FigkW.png" alt="chat window screenshot"></a></p>