0

I want to do public chat with firebase database to pass classes at the University. I have problem because, I learn how to write this and I watched tutorials on youtube. I found project and I did, but firebase change a few things with FirebaseListAdapter. For that I changed code.

Currently I have this:

I know what's happen (probably) , but I need idea how to fix It.

1) ActivityChat is based on tutorials, on the internet.

public class ActivityChat extends AppCompatActivity {
    private static int SIGN_IN_REQUEST_CODE = 1;
    private FirebaseListAdapter<ChatMsg> adapter;
    Query query = FirebaseDatabase.getInstance().getReference().child("Chats").limitToLast(50);

    FirebaseListOptions<ChatMsg> options = new FirebaseListOptions.Builder<ChatMsg>()
            .setQuery(query, ChatMsg.class)
            .setLayout(R.layout.activity_chat)
            .build();
    EditText input;
    RelativeLayout chat;
    FloatingActionButton fab;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SIGN_IN_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                Toast.makeText(getApplicationContext(), "Pomyślnie zalogowany!", Toast.LENGTH_SHORT).show();

            } else {
                Toast.makeText(getApplicationContext(), "Nie można zalogować się. Spróbuj później.", Toast.LENGTH_SHORT).show();
            }

        }
    }

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

        input = (EditText) findViewById(R.id.input);
        chat = (RelativeLayout) findViewById(R.id.activity_chat);
        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseDatabase.getInstance().getReference("Chats").push().setValue(new ChatMsg(input.getText().toString(),
                        FirebaseAuth.getInstance().getCurrentUser().getEmail()));
                input.setText("");
                input.requestFocus();
                displayChatMessage();
            }

        });


        if (FirebaseAuth.getInstance().getCurrentUser() == null) {
            startActivityForResult(AuthUI.getInstance().createSignInIntentBuilder().build(), SIGN_IN_REQUEST_CODE);
        } else {
            Toast.makeText(getApplicationContext(), "Witaj: " + FirebaseAuth.getInstance().getCurrentUser().getEmail(), Toast.LENGTH_SHORT).show();
        }


    }

    private void displayChatMessage() {
        ListView listMessage = (ListView) findViewById(R.id.list_of_message);
        adapter = new FirebaseListAdapter<ChatMsg>(options) {
            @Override
            protected void populateView(@NonNull View v, @NonNull ChatMsg model, int position) {
                TextView messageText, messageUser, messageTime;
                messageText = (TextView) v.findViewById(R.id.message_text);
                messageUser = (TextView) v.findViewById(R.id.message_user);
                messageTime = (TextView) v.findViewById(R.id.message_time);

                messageText.setText(model.getMessageText());
                messageUser.setText(model.getMessageUser());
                messageTime.setText(DateFormat.format("dd-MM-yyyy (HH:mm:ss)", model.getMessageTime()));
            }
        };
        listMessage.setAdapter(adapter);
    }

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


    @Override
    protected void onStop() {
        super.onStop();
        adapter.stopListening();
    }
}

2) When I push button to go to the Chat, I see activity for 2 seconds and I have crash apk (Apk has stopped).

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.bsk69.spystreamgui, PID: 6214
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.bsk69.spystreamgui/com.example.bsk69.spystreamgui.ActivityChat}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.database.FirebaseListAdapter.startListening()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2763)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2824)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6351)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:786)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.database.FirebaseListAdapter.startListening()' on a null object reference
        at com.example.bsk69.spystreamgui.ActivityChat.onStart(ActivityChat.java:222)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1249)
        at android.app.Activity.performStart(Activity.java:6792)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2726)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2824) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6351) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:786) 
Application terminated.
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

0

The problem is caused by a NullPointerException on ActivityChat.java:222, which is the last line of your onStart method:

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

The error means that you're calling startListening() before you've created the adapter. Since you only create the adapter in displayChatMessage when the user clicks a button, you can blindly tell it to start connecting to the database in onStart, which happens before the user clicks the button.

Most likely you can simply start listening straight when you create the adapter:

private void displayChatMessage() {
    ListView listMessage = (ListView) findViewById(R.id.list_of_message);
    adapter = new FirebaseListAdapter<ChatMsg>(options) {
        ...
    };
    listMessage.setAdapter(adapter);
    adapter.startListening();
}

You'll also need to change the onStop, since this may be called without the user every clicking the button. The simplest fix there is:

@Override
protected void onStop() {
    super.onStop();
    if (adapter != null) {
        adapter.stopListening();
    }
}

These null pointer exceptions are extremely common in programming, so I highly recommend reading What is a NullPointerException, and how do I fix it?.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks I check It, because I learn writing. Currently I back to my first problem. I did a lot of combinations to fix It. When I write something and push "send button", I have crash, but message is saved in database.I need to see message in my listView: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.bsk69.spystreamgui.ActivityChat$2.populateView(ActivityChat.java:209) at com.example.bsk69.spystreamgui.ActivityChat$2.populateView(ActivityChat.java:201) –  Jan 09 '19 at 20:01
  • That's in another location than the one you had earlier. If you follow the steps in the question/answer I linked, you should be able to figure out what object is `null`. You'll need to initialize that object before you call `setText()` on it, similar to what I did for `adapter` in my answer. – Frank van Puffelen Jan 09 '19 at 20:11
  • OK, WORKING ! My fail was with layout. I wrote activity_chat.xml, but I should list_item.xml. Thanks for help again ! Still is working. –  Jan 09 '19 at 20:20
  • Good to hear. Happy hacking! – Frank van Puffelen Jan 09 '19 at 20:24