Неорганизованные сообщения чата в моем приложении чата с использованием Firebase

#java #android #firebase #chat

# #java #Android #firebase #Чат

Вопрос:

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

Когда я отправляю только текст:

Перед прокруткой https://i.stack.imgur.com/2NMVHl.jpg

После прокрутки https://i.stack.imgur.com/2Nxpc.jpg (то же самое)

Когда я отправляю изображение с текстом

Перед прокруткой https://i.stack.imgur.com/rS6Mx.jpg

После прокрутки https://i.stack.imgur.com/OP5DK.jpg

В моем коде есть два места, откуда можно загрузить сообщение (изображение или текст).

  1. Для отправки сообщения изображения:

Брифинги — здесь я загружаю изображение в хранилище, а затем извлекаю его URL. Затем я сохраняю URL-адрес в firestore в виде строки (которую я позже использую для загрузки изображения с помощью Picasso) вместе с другими деталями сообщения.

             final Long currentTime = System.currentTimeMillis();
            final String time = currentTime   "";
            final StorageReference fileref = storageReference.child("Image Messages")
                    .child(uid   time);
            StorageTask uploadTask = fileref.putFile(uri);
            uploadTask.continueWithTask(new Continuation() {
                @Override
                public Object then(@NonNull Task task) throws Exception {
                    if(!task.isSuccessful()){
                        throw task.getException();
                    }
                    return fileref.getDownloadUrl();
                }
            }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    if(task.isSuccessful()){
                        Uri downloadUrl = task.getResult();
                        String myUrl = downloadUrl.toString();

                        Map<String, Object> chat = new HashMap<>();
                        chat.put("message", myUrl);
                        chat.put("time", currentTime);
                        chat.put("sender", mUser.getUid());
                        chat.put("groupId",Gid);
                        chat.put("type","image");
                        chat.put("username",preferences.getData("username"));
                        chat.put("name",preferences.getData("usernameAdded"));
                        firestore.collection("aGroups").document(Gid).collection("Chat")
                                .add(chat).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                            @Override
                            public void onSuccess(DocumentReference documentReference) {
                                showChatMessages();
                                dialog.dismiss();
                                Toast.makeText(getApplicationContext(),"Message Sent", Toast.LENGTH_SHORT).show();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Toast.makeText(getApplicationContext(),"Error", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }
            });
 
  1. Для отправки текстового сообщения

Брифинги — здесь я загружаю сообщение и его детали

  Map<String, Object> chat = new HashMap<>();
                    chat.put("message", message.getText().toString());
                    chat.put("time", System.currentTimeMillis());
                    chat.put("sender", mUser.getUid());
                    chat.put("groupId",Gid);
                    chat.put("type","text");
                    chat.put("username",preferences.getData("username"));
                    chat.put("name",preferences.getData("usernameAdded"));
                    firestore.collection("aGroups").document(Gid).collection("Chat")
                            .add(chat).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                        @Override
                        public void onSuccess(DocumentReference documentReference) {
                            Toast.makeText(ChatInterface.this, "Message Sent", Toast.LENGTH_SHORT).show();
                            showChatMessages();
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Toast.makeText(getApplicationContext(),"Error", Toast.LENGTH_SHORT).show();
                        }
                    });
 

Здесь я добавляю обратные вызовы

 private void showChatMessages() {
        firestore.collection("aGroups").document(Gid).collection("Chat")
                .orderBy("time", Query.Direction.DESCENDING)
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
                if(error != null){
                    Log.d("Check", "listen failed: "   error.getMessage());
                }

                else{
                    Log.d("Check", "Snapshot worked");
                    List<ChatModel> list = new ArrayList<>();
                    list.clear();
                    for(QueryDocumentSnapshot query : value){
                    list.add(new ChatModel(
                              query.getString("groupId")
                            , query.getId()
                            , query.getString("message")
                            , query.getString("sender")
                            , query.getLong("time")
                            , query.getString("name")
                            , query.getString("username")
                            , query.getString("type")
                    ));
                }
                recycler_interface.setAdapter(new RealChatRecyclerInterface(mUser.getUid(),list));
            }}
        });
    }
 

Я добавляю все свои RealChatRecyclerInterface сообщения в эту ссылку pastebin.

Ответ №1:

Используйте holder.setIsRecyclable(false); в своем RealChatRecyclerInterface

Комментарии:

1. Вау!! Я злился на это в течение 7 дней. Миллион благодарностей вам!