Firebase: cannot update messages after send

I have a conversation system using firebase. I get all the users’ id that have sent me messages. So in my database I get their data and list with a v-for.

After listing them I search their messages to list in a message box below each user.

Everything is working fine but I cannot get sent messages instantly after sending them.

Is there a way to make this work without replacing all data object?

<div v-if="isLoading == false" class="row messages-row" v-for="(item, index) in memberData" :key="index">
				<div class="col-md-4 col-12">
					<div class="messages-profile-infos">
						<div class="messages-profile-infos-img img-fluid"
							v-bind:style="{'background-image': 'url(http://localhost/backend/member/'+item.memberProfileImg + ')' }">
						</div>
						<div class="messages-profile-infos-text">
							<p>{{ item.memberName }} {{ item.memberLastname }}</p>
							<p>{{ item.memberCity }} - {{ item.memberState }}</p>
						</div>
					</div>
				</div>
				<div class="col-md-2 col-12">
					<div class="messages-btns">
						<button class="btn trade-btn" @click="showConversation(item.memberID)">Negociação</button>
					</div>
				</div>
				<div class="col-md-6 col-12">
					<div class="messages-status">
						<a class="btn border btn-circle text-uppercase confirm-service-btn" href="javascript:void(0);">
							Confirmar Serviço
						</a>
						<a class="btn border btn-circle text-uppercase cancel-service-btn"
							href="javascript:void(0);">Cancelar</a>
					</div>
				</div>

				<!-- conversation box -->
				<div v-if="memberBox == item.memberID" class="conversation-container" :id="item.memberID">
					<div v-for="(tour, index) in item.tours" :key="index" id="tourOnConversation"
						class="tourOnConversation">
						<span>Passeio escolhido:</span>
						<span><strong>{{ tour.title }}</strong></span>
					</div>
					<div id="messages-container" class="messages-container" :key="item.memberID">
						<div v-for="message in item.messages" class="d-flex"
							:class="[message.uid != myID ?'justify-content-start':'justify-content-end']">
							<span class="badge badge-pill"
								:class="[message.uid != myID ?'badge-primary':'badge-secondary']">{{ message.message }}</span>
						</div>
					</div>
					<div class="message-typing-container">
						<form id="messages_form" action="" method="POST">
							<div class="typing-container">
								<input id="message" v-model="messages" type="text" class="message-typing"
									autocomplete="off" />
								<input class="send-message" type="submit" value="Enviar"
									@click="sendMessage(item.memberID, item.tour)" />
							</div>
						</form>
					</div>
				</div>
				<hr />
			</div>
		</div>
</div>
let app = new Vue({
    el: '#app',
    data() {
        return {
            memberData: {},
            myMessages: [],
            memberMessages: [],
            myID: userID,
            messages: '',
            messageBox: 0,
            conversation: {},
            isLoading: true,
            memberBox: 0
        }
    },
    mounted() { },
    created: function () {
        this.getAllMessages();
    },
    methods: {
        scrollBox: function () {
            let messagebox = document.querySelector('#messages-container');
            messagebox.scrollTop = messagebox.scrollHeight;
        },
        getAllMessages: function () {
            // console.log(this.myID);
            let distinct = '';

            firebase.firestore().collection('private-messages').where('memberID', '==', `${this.myID}`)
                .orderBy('date').onSnapshot(res => {

                    let members = [];
                    res.forEach(doc => {
                        members.push(doc.data().uid);
                        // console.log(doc.data().tour);
                    });
                    distinct = Array.from(new Set(members));
                    // console.log(distinct);

                    this.getUserToTalk(distinct);
                });
        },
        getMyMessages: function (memberID) {

            let myMessages = [];
            firebase.firestore().collection('private-messages').where('uid', '==', `${this.myID}`).where('memberID', '==', `${memberID}`)
                .orderBy('date').onSnapshot(res => {
                    res.forEach(doc => {
                        myMessages.push(doc.data());
                    });
                });
            // this.myMessages = myMessages;
            return myMessages;
        },
        getMyMessages: function (memberID) {

            let myMessages = [];
            firebase.firestore().collection('private-messages').where('uid', '==', `${this.myID}`).where('memberID', '==', `${memberID}`)
                .orderBy('date').onSnapshot(res => {
                    res.forEach(doc => {
                        myMessages.push(doc.data());
                    });
                });
            // this.myMessages = myMessages;
            return myMessages;
        },
        getMessages: function (memberID) {

            let messages = [];
            firebase.firestore().collection('private-messages').where('uid', '==', `${memberID}`).where('memberID', '==', `${this.myID}`)
                .orderBy('date').onSnapshot(res => {
                    res.forEach(doc => {
                        messages.push(doc.data());
                    });
                });
            // this.memberMessages = messages;
            return messages;
        },
        getUserToTalk: function (memberID) {

            axios.post('http://localhost/backend/getMemberToTalk.php', {
                "token": token,
                "whoToTalkTo": memberID,
                // "tourID": tourID
            }).then(response => {

                // console.log(response.data);
                if (response.data != "Error getting user data and tour" && response.data != "Error receiving data") {

                    let joinedData = [];

                    response.data.forEach(res => {

                        let messages = this.getMessages(res.memberID);
                        let myMessages = this.getMyMessages(res.memberID);
                        // console.log(messages);
                        // console.log(myMessages);

                        let conversation = [];
                        let data = {};

                        setTimeout(() => {
                            conversation = [...messages, ...myMessages];

                            conversation.sort(function (a, b) {
                                return a.date - b.date;
                            });
                            // console.log(conversation);

                            if (conversation.length > 0) {
                                data = {
                                    memberID: res.memberID,
                                    memberProfileImg: res.memberProfileImg,
                                    memberName: res.memberName,
                                    memberLastname: res.memberLastname,
                                    memberCity: res.memberCity,
                                    memberState: res.memberState,
                                    messages: conversation,
                                    tour: conversation[0].tour
                                }
                                this.isLoading = false;
                            } else {
                                this.isLoading = true;
                                this.getAllMessages();
                            }

                            joinedData.push(data);
                        }, 2000);

                    });
                    // console.log(joinedData);

                    this.memberData = joinedData;
                    console.log(this.memberData);
                } else {
                    console.log(response.data);
                }
            }).catch(error => {
                console.log(error);
            });
        },
        sendMessage: function (memberID, tourID) {

            $('#messages_form').on('submit', (e) => {
                e.preventDefault();
                let message = this.messages;

                if (!message.trim()) return;
                // console.log(message);
                this.messages = '';
                let messages = [];

                console.log(this.memberData);

                 firebase.firestore().collection('private-messages').add({
                     uid: JSON.stringify(this.myID),
                     memberID: JSON.stringify(memberID),
                     message: message,
                     date: Date.now(),
                     tour: tourID
                 }).then(res => {
                     // console.log('Message sent');

                }).catch(e => console.log(e));

            });
        },
        showConversation: function (memberID) {

            // console.log(memberID);
            // let id = $('.conversation-container').attr('id');
            this.memberBox = memberID;
            if (this.memberBox == memberID) {
                $('.conversation-container').toggle("fast");
            }
        }
    },
    // computed:{
    //     messages: function () {
    //         return _.orderBy(this.messages, 'date');
    //     }
    // },
    mounted() {
    },
});

I see all looks okay but if you are not getting the real time updates, chances are that you probably need to create an index for your search query. Firebase normally denies queries that are not indexed. You can probably try look at the error logs. And also, you dont need to call onSnapshot listener every time a method is called. I suggest you have the onSnaphot listener in the created or mounted hook

Hi, I created all indexes that were logged in console.log by firebase. I think your suggestion about onSnapshot is the key. Could you help me with some code? I still cannot figure it out how to update this.memberData to display the messages on each message box

I’ve put snapshot in mounted(). Every message sent it gets data as expected. But I’m not able to update this.memberData to refresh the chat.

Can you help me with that?

mounted(){
let messages = [];
firebase.firestore().collection('messages').where('memberID', '==', `${this.myID}`).orderBy('date').onSnapshot(res => {
    res.forEach(doc => {
          messages.push(doc.data());
    });
    console.log(messages);
});

let mymessages = [];
firebase.firestore().collection('messages').where('uid', '==', `${this.myID}`).orderBy('date').onSnapshot(res => {
    res.forEach(doc => {
          mymessages.push(doc.data());
    });
    console.log(mymessages);
});
}