Почему из Firebase Cloud Firestore я получаю список данных, а RecyclerView отображает только последние элемента из этого списка

MainActivity - тут я получаю данные и передаю список в RecyclerView

class MainActivity : AppCompatActivity() {

    private var chatContainer: MutableList<Chat> = mutableListOf()
    private val adapter = RecyclerChatAdapter(chatContainer)

    private var firstList: MutableList<String> = mutableListOf()
    private var secondList: MutableList<String> = mutableListOf()

    private var chatMessage = ""

    private val firestoreChat by lazy {
        FirebaseFirestore.getInstance().collection("Chat")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        firestoreChat.addSnapshotListener { documentSnapshot, _ ->
            chatContainer.clear()
            when {
                documentSnapshot != null -> {
                    for (dc in documentSnapshot.documentChanges) {
                        when (dc.type) {
                            DocumentChange.Type.ADDED -> {

                                val chat = dc.document.toObject(Chat::class.java)
                                chatContainer.add(chat) // Добавление данных в Recycler
                                for (i in chatContainer) {
                                    Log.d("efefe", "Список из MainActivity $i")
                                }
                                adapter.notifyDataSetChanged()
                            }
                        }
                    }
                }
            }
        }

        recyclerview.layoutManager =
            LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false)
        recyclerview.setHasFixedSize(true)
        recyclerview.adapter = adapter

        chatField.setOnEditorActionListener { _, actionId, event ->
            if (event != null && event.keyCode == KeyEvent.KEYCODE_ENTER || actionId == EditorInfo.IME_ACTION_SEND) {
                sendMessage()
            }

            false
        }
    }

    private fun sendMessage() {
        chatMessage = chatField.text.toString()

        if (chatMessage != "") {
            firstList.add(chatMessage)
        }

        val firebaseData = mutableMapOf<String, MutableList<String>>()
        firebaseData["firstMessage"] = firstList
        firebaseData["secondMessage"] = firstList

        firestoreChat.document("messages").set(firebaseData)
        chatField.text?.clear()
    }
}

RecyclerChatAdapter - Recycler адаптер

class RecyclerChatAdapter(private var chatMessageContainer: MutableList<Chat>) :
    RecyclerView.Adapter<ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
        ViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.chat_content, parent, false)
        )

    override fun getItemCount(): Int = chatMessageContainer.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) = holder.itemView.run {

        val currentPosition = chatMessageContainer[position]

        currentPosition.firstMessage.forEach { message ->
            firstUserMessage.text = message
            Log.d("efefe", "Список из Recycler firstMessages $message")
        }

        currentPosition.secondMessage.forEach { message ->
            secondUserMessage.text = message
            Log.d("efefe", "Список из Recycler secondMessages $message")
        }
    }
}

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

Chat - модель

data class Chat(var firstMessage: List<String>, var secondMessage: List<String>) {

    constructor(): this(emptyList(), emptyList())
}

recycler_content - экран для RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/firstUserMessageCard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="10dp"
        app:cardBackgroundColor="#ECEDF1"
        app:cardCornerRadius="15dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/secondUserMessageCard">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/firstUserMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            android:layout_marginTop="7dp"
            android:layout_marginEnd="30dp"
            android:layout_marginBottom="7dp"
            android:text="Привет"
            android:textColor="#000"
            android:textSize="16sp" />

    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:id="@+id/secondUserMessageCard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:layout_marginEnd="20dp"
        app:cardBackgroundColor="#CCE4FF"
        app:cardCornerRadius="15dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/secondUserMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="15dp"
            android:layout_marginTop="7dp"
            android:layout_marginEnd="30dp"
            android:layout_marginBottom="7dp"
            android:text="Привет"
            android:textSize="16sp"
            android:textColor="#000" />

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

Получается, когда в Firestore 1 элемент, то все окей. А когда, 2 и более, то recyclerview отображаетвведите сюда описание изображения введите сюда описание изображениятолько последний элемент спискавведите сюда описание изображениявведите сюда описание изображения


Ответы (1 шт):

Автор решения: Andrew

Для начала в onCreate() уберите эту строку:

chatContainer.clear()

Нет смысла чистить только созданный пустой список. Дальше я бы вам советовал следующим образом. Для начала при объявлении адаптера не нужно сразу ему передавать список:

lateinit var adapter: RecyclerChatAdapter

Дальше как только ваш список заполнен вы это проверяете в цикле и инициализируете адаптер:

when {
    documentSnapshot != null -> {
        for (dc in documentSnapshot.documentChanges) {
            when (dc.type) {
                DocumentChange.Type.ADDED -> {
                    val chat = dc.document.toObject(Chat::class.java)
                    chatContainer.add(chat) // Добавление данных в Recycler
                    if(chatContainer.size == documentSnapshot.documentChanges)
                    {
                        adapter = RecyclerChatAdapter(chatContainer)
                    }
                }
            }
        }
    }
}

и дальше сеттинг адаптера как и было у вас в вашем примере. Так же второй вариант как решить вашу проблему, но не уверен что получится, можно в цикле там где вы выводите сообщение в лог обновлять адаптер:

for (i in chatContainer) {
    adapter.notifyDataSetChanged()
}
→ Ссылка