Как предотвратить дублирование моих чатов, когда кто-то отправляет сообщение в Android Studio firebase - PullRequest
0 голосов
/ 29 мая 2020

Я разрабатываю простое приложение для чата basi c с использованием базы данных firebase в реальном времени, и я все спроектировал хорошо, однако у меня возникла одна проблема со светом. Мои чаты продолжают дублировать себя на странице входящих сообщений (страница, на которой чаты расположены для того, чтобы пользователь мог выбрать, какой чат он хочет открыть и начать разговор).

Я прикрепил изображение того, что я имею в виду ниже. Скриншот экрана телефона

Код, который я использую для получения чатов и отображения их в представлении ресайклера, приведен ниже. У меня есть каталог под названием Conversations в моей БД, в котором хранится идентификатор пользователя, и под ним находится дочерний элемент каждого человека, с которым он разговаривает, под которым находится последнее сообщение и видное логическое значение.

Структура базы данных

Ниже приведен код

 convoref = FirebaseDatabase.getInstance().getReference().child("Conversations").child(currentUid);

а затем ..

  public void getConvoIds() {
    convoref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for(DataSnapshot convo : dataSnapshot.getChildren()){

                    boolean isMessageSeen = false;
                    String lastMessage = "";

                    if(convo.child("seen").getValue() != null) {
                        isMessageSeen = (boolean) convo.child("seen").getValue();
                    }else{
                        Log.i("nolastseen", "location is null");
                    }

                    if(convo.child("lastMessage").getValue() != null) {
                        lastMessage = convo.child("lastMessage").getValue().toString();
                    }else{
                        Log.i("nolastMessage", "location is null");
                    }

                    Log.i ("the_convo_partner_key", convo.getKey());
                    Log.i ("lastseenmessage", lastMessage);
                    Log.i ("seenstate", String.valueOf(isMessageSeen));
                    FetchConvoInfo(convo.getKey(), isMessageSeen, lastMessage );
                }
            }
        }

конво выборки информация functuion ниже

  public void FetchConvoInfo(final String key, final boolean isMessageSeen, final String lastMessage){
        FirebaseDatabase.getInstance().getReference().child("Users").child(key).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                boolean chatExists = false;
                String username = "";
                String thumbnail = "";
                String chatPartner;

                chatPartner = key;

                if(dataSnapshot.child("username").exists()){
                    username = dataSnapshot.child("username").getValue().toString();
                }

                if(dataSnapshot.child("thumbnail").exists()){
                    thumbnail = dataSnapshot.child("thumbnail").getValue().toString();
                }

                ConvoClass obj= new ConvoClass(chatPartner, username, thumbnail, isMessageSeen, lastMessage);
                resultConvos.add(obj);
                mConvoAdapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });
}

Любая помощь будет принята с благодарностью. Кажется, я не могу понять, почему чат дублируется.

1 Ответ

0 голосов
/ 29 мая 2020

В вашем методе onDataChanged вы просматриваете каждого дочернего элемента dataSnapshot. Каждый дочерний элемент снимка данных указывает на конкретный разговор этого конкретного currentUid парня. Итак, когда вы просматриваете каждого дочернего элемента dataSnapshot, вы добавляете всех его дочерних элементов в listview или recyclerview (я не знаю, что вы используете. Но вы добавляете его в адаптер). Таким образом, вы снова и снова добавляете старые данные всякий раз, когда необходимо добавить новые данные. Отсюда - повторяющиеся данные.

Есть два общих решения.

Первый - наивный метод. Делай то, что делаешь прямо сейчас. Но при добавлении элемента (чат, я думаю, вы назовете его в своем случае) в адаптер, проверьте, присутствует ли он уже в контейнере resultConvos. Это предотвратит добавление повторяющихся чатов. Я уверен, что и вам очевидно, почему этот метод неэффективен. Вам без надобности приходится go в каждом разговоре человека. Для добавления одного элемента требуется O (n) времени.

Второй метод является рекомендуемым. Удалите весь код ValueEventListener. Вместо этого используйте ChildEventListener. Не знаю, знаете ли вы об этом. Отметьте это .

ChildEventListener имеет в основном 4 метода вместо onDataChanged. Среди них вам потребуется onChildAdded. Как и ваш onDataChanged, у него есть один аргумент - снимок данных. Но этот снимок данных содержит только недавно добавленный дочерний элемент, тогда как снимок данных в onDataChanged содержит все данные разговоров этого конкретного пользователя (то есть весь список). Таким образом, используя снимок данных, предоставленный onChildAdded, вы можете напрямую добавить только этот чат к адаптеру, что занимает время O (1).

Подробнее о ChildEventListener читайте в этой ссылке, которую я прикрепил

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...