-1

While trying to build a texting app and I added a Firebase value event listener which is called from onCreate() (...callFirebase() function), all of this looked good to me before I realised my RecyclerView stopped updating itself (..messageAdapter.notifyItemInserted(messageList.size()-1)) when I pressed the send button. And RecyclerView starts working properly as soon as I comment the callFirebase() line in onCreate(). Please look at the code and let me know that I did wrong.

package com.siddhantkushwaha.www.raven;

import android.content.Intent;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.EditText;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class chat_room extends AppCompatActivity {

    private FloatingActionButton sendButton;
    private EditText chatEditText;
    private String uid_1;
    private String uid_2;
    private ArrayList<Message> messageList;
    private MessageAdapter messageAdapter;
    private RecyclerView recyclerView;
    private String threadId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_room);

        Intent intent = getIntent();
        uid_1 = intent.getStringExtra("sender");
        uid_2 = intent.getStringExtra("receiver");

        sendButton = findViewById(R.id.sendButton);
        chatEditText = findViewById(R.id.chatEditText);

        recyclerView = findViewById(R.id.messageRecyclerView);
        recyclerView.setHasFixedSize(true);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        messageList = new ArrayList();
        messageAdapter = new MessageAdapter(this, messageList, uid_1);
        recyclerView.setAdapter(messageAdapter);

        callFirebase();
    }

    private void callFirebase() {

        threadId = null;
        Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_1) + "/" + uid_2).addListenerForSingleValueEvent(

                new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {

                        if(dataSnapshot.getValue() != null) {

                            threadId = dataSnapshot.getValue().toString();
                            System.out.println(threadId);
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                }
        );
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    public void sendButtonClicked(View view) {
        sendMessage();
    }

    private void sendMessage() {

        String text_message = chatEditText.getText().toString();
        if(text_message.length() == 0)
            return;
        messageList.add(new Message(text_message, uid_1, uid_2));
        messageAdapter.notifyItemInserted(messageList.size()-1);
        recyclerView.smoothScrollToPosition(messageAdapter.getItemCount());
        chatEditText.setText("");

        if(threadId != null) {

            addToThread(new Message(text_message, uid_1, uid_2));
        }
        else {

            createThread(new Message(text_message, uid_1, uid_2));

        }
    }

    private void createThread(Message _message) {

         String thread_key = Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsRoot()).push().getKey();
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadDetails(thread_key)).setValue(new ThreadDetails(uid_1, uid_2));
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadMessageList(thread_key)).push().setValue(_message);
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_1) + "/" + uid_2).setValue(thread_key);
         Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadsList(uid_2) + "/" + uid_1).setValue(thread_key);

         threadId = thread_key;
    }

    private void addToThread(Message _message) {
        Util.getDatabase().getInstance().getReference(PathUtil.pathToThreadMessageList(threadId)).push().setValue(_message);
    }
 }
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Siddhant
  • 573
  • 6
  • 14

1 Answers1

0

This is happening because you are assigning a value to the threadId variable inside the onDataChange() method and you trying to use it outside that method. Just declaring a variable as global doesn't solve your problem because onDataChange() method has asynchronous behaviour, which means that is called even before you are trying to get the data from the database. A quick fix would be to use that variable only inside that method, or to use the last part of my answer from this post. I also recommend you see this video.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193