0

when i build my project no error appears but when the application start it crashed and give me that error in line 97 in the for loop [ for (User user1 : mUsers) ] the error is: FATAL EXCEPTION: main Process: com.example.chatapp, PID: 9908 java.util.ConcurrentModificationException

i didn't understand that error and why this error appears.

here is my code:

private UserAdapter userAdapter;
private List<User> mUsers;
FirebaseUser fuser;
DatabaseReference reference;
private List<String>usersList;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_chats, container, false);

    recyclerView = view.findViewById(R.id.recycle_view);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

    fuser = FirebaseAuth.getInstance().getCurrentUser();

    usersList = new ArrayList<>();

    reference = FirebaseDatabase.getInstance().getReference("Chat");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            usersList.clear();

            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                Chat chat = snapshot.getValue(Chat.class);

                assert chat != null;
                if (chat.getSender().equals(fuser.getUid())){
                    usersList.add(chat.getReceiver());
                }
                if (chat.getReceiver().equals(fuser.getUid())){
                    usersList.add(chat.getSender());
                }
            }
            readChats();

        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

    return view;
}

public void readChats(){
    mUsers = new ArrayList<>();
    reference = FirebaseDatabase.getInstance().getReference("Users");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            mUsers.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()){
                User user = snapshot.getValue(User.class);

                // display user from chats
                for (String id : usersList){

                    if (user.getId().equals(id)){
                        if (mUsers.size() != 0){
                            for (User user1 : mUsers){   // error here
                                if (!user.getId().equals(user1.getId())){
                                    mUsers.add(user);
                                }
                            }
                        }else {
                            mUsers.add(user);
                        }
                    }
                }
            }

            userAdapter = new UserAdapter(getContext(), mUsers);
            recyclerView.setAdapter(userAdapter);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
}

}

1 Answers1

2

Here :

for (User user1 : mUsers){   // error here
        if (!user.getId().equals(user1.getId())){
            mUsers.add(user);
        }
}

You add an element in the collection while you iterate on that with an Iterator. That is not allowed. Note that the enhanced for loop that you use for (User user1 : mUsers) after compilation is expressed as an Iterator.

To overcome that limitation you could use a ListIterator that is (emphasis is mine) :

An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list.

ListIterator<User> listIteratorUser = mUsers.listIterator();
while(listIteratorUser.hasNext()){   
      User user1 = listIteratorUser.next();
      if (!user.getId().equals(user1.getId())){
          listIteratorUser.add(user);
      }
  }
davidxxx
  • 125,838
  • 23
  • 214
  • 215