0

I'm trying to retrieve data to a RecyclerView from Firebase. But I am experiencing a NullPointerException. I have input the necessary children to be able to retrieve the data but I am not able to. What could be wrong? Below is my code...

ChatActivity

package com.dreamlazerstudios.gtuconline;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChatActivity extends AppCompatActivity {

private DatabaseReference rootRef, messagesRef;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String userID;
private String mChatUser;

private ImageButton chat_add_btn, chat_send_btn;
private EditText enter_message;

List<DataSnapshot> listData;
RecyclerView recyclerView;
ChatActivity.MyAdapter adapter;

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

    recyclerView = findViewById(R.id.messages_list);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    messagesRef = FirebaseDatabase.getInstance().getReference();

    listData = new ArrayList<>();
    adapter = new ChatActivity.MyAdapter(listData);
    adapter.setHasStableIds(true);

    chat_add_btn = findViewById(R.id.chat_add_btn);
    chat_send_btn = findViewById(R.id.chat_send_btn);
    enter_message = findViewById(R.id.chat_message_view);

    loadMessages();

    rootRef = FirebaseDatabase.getInstance().getReference();
    mAuth = FirebaseAuth.getInstance();
    final FirebaseUser user = mAuth.getCurrentUser();
    userID = user.getUid();

    mChatUser = getIntent().getStringExtra("user_id");
    String username = getIntent().getStringExtra("user_name");
    setTitle(username);

    rootRef.child("Chat").child(userID).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            if (!dataSnapshot.hasChild(mChatUser)) {
                Map chatAddMap = new HashMap();
                chatAddMap.put("seen", false);
                chatAddMap.put("timestamp", ServerValue.TIMESTAMP);

                Map chatUserMap = new HashMap();
                chatUserMap.put("Chat/" + userID + "/" + mChatUser, chatAddMap);
                chatUserMap.put("Chat/" + mChatUser + "/" + userID, chatAddMap);

                rootRef.updateChildren(chatUserMap, new DatabaseReference.CompletionListener() {
                    @Override
                    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                        if (databaseError != null) {

                            Log.d("CHAT_LOG", databaseError.getMessage().toString());

                        }
                    }
                });
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    chat_send_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            sendMessage();
        }
    });

}

private void loadMessages() {
    messagesRef = FirebaseDatabase.getInstance().getReference().child("gtuconline").child("messages").child(userID).child(mChatUser);

    messagesRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            Messages messages = dataSnapshot.getValue(Messages.class);

            listData.add(dataSnapshot);
            recyclerView.setAdapter(adapter);
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void sendMessage() {
    String message = enter_message.getText().toString();
    if (!TextUtils.isEmpty(message)) {

        String current_user_ref = "messages/" + userID + "/" + mChatUser;
        String chat_user_ref = "messages/" + mChatUser + "/" + userID;

        DatabaseReference user_message_push = rootRef.child("messages").child(userID).child(mChatUser).push();

        String push_id = user_message_push.getKey();

        Map messageMap = new HashMap();
        messageMap.put("message", message);
        messageMap.put("seen", false);
        messageMap.put("type", "text");
        messageMap.put("time", ServerValue.TIMESTAMP);

        Map messageUserMap = new HashMap();
        messageUserMap.put(current_user_ref + "/" + push_id, messageMap);
        messageUserMap.put(chat_user_ref + "/" + push_id, messageMap);

        enter_message.setText("");

        rootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                if (databaseError != null) {
                    Log.d("CHAT_LOG", databaseError.getMessage());
                }

            }
        });
    }
}

public class MyAdapter extends RecyclerView.Adapter<ChatActivity.MyAdapter.ViewHolder> {

    List<DataSnapshot> list;

    public MyAdapter(List<DataSnapshot> List) {
        this.list = List;
    }

    @Override
    public void onBindViewHolder(@NonNull final ChatActivity.MyAdapter.ViewHolder holder, final int position) {

        final DataSnapshot studentSnapshot = list.get(position);

        final Messages students = studentSnapshot.getValue(Messages.class);

        assert students != null;
        holder.messageText.setText(students.getMessage());


    }

    @NonNull
    @Override
    public ChatActivity.MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout, parent, false);

        return new ChatActivity.MyAdapter.ViewHolder(view);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView messageText, timeText, userName;

        public ViewHolder(View itemView) {
            super(itemView);

            messageText = itemView.findViewById(R.id.user_single_message);
            timeText = itemView.findViewById(R.id.user_single_time);
            userName = itemView.findViewById(R.id.user_single_name);

        }

    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}


}

My Model Class

package com.dreamlazerstudios.gtuconline;

/**
* Created by Gabriel Hagan on 23/05/2018 at 17:18.
*/
public class Messages {

private String message, type;
private long time;
private boolean seen;

public Messages(String message, String type, long time, boolean seen) {
    this.message = message;
    this.type = type;
    this.time = time;
    this.seen = seen;
}

public Messages() {
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public long getTime() {
    return time;
}

public void setTime(long time) {
    this.time = time;
}

public boolean isSeen() {
    return seen;
}

public void setSeen(boolean seen) {
    this.seen = seen;
}
}

My xml layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChatActivity">

<android.support.v7.widget.RecyclerView
    android:id="@+id/messages_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/text_layout">

</android.support.v7.widget.RecyclerView>

<LinearLayout
    android:id="@+id/text_layout"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    android:weightSum="100">


    <ImageButton
        android:id="@+id/chat_add_btn"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20"
        android:background="@color/white"
        android:contentDescription="@string/image"
        android:src="@drawable/ic_add_black_24dp" />

    <EditText
        android:id="@+id/chat_message_view"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout_weight="60"
        android:background="@color/white"
        android:ems="10"
        android:hint="Send a message"
        android:inputType="none"
        android:paddingEnd="3dp"
        android:paddingStart="3dp"
        android:paddingTop="5dp"
        android:textSize="17sp" />

    <ImageButton
        android:id="@+id/chat_send_btn"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20"
        android:background="@color/white"
        android:contentDescription="@string/send"
        android:src="@drawable/ic_send_black_24dp" />


</LinearLayout>

</RelativeLayout>

Layout for the recyclerview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:weightSum="1"
android:layout_height="wrap_content">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginTop="5dp"
    android:padding="2dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textStyle="bold"
            android:id="@+id/user_single_name"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:text="@string/full_name"
            android:textColor="@android:color/background_dark"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/user_single_time"
            android:layout_width="60dp"
            android:layout_height="30dp"
            android:layout_marginTop="10dp"
            android:text="00:00"
            android:textColor="@android:color/background_dark"
            android:layout_marginStart="10dp"/>

    </LinearLayout>

    <TextView
        android:id="@+id/user_single_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:layout_marginStart="10dp"
        android:text="Message Text"
        android:textSize="12sp" />

    <View
        android:id="@+id/first_view"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="5dp"
        android:layout_marginStart="2dp"
        android:layout_marginEnd="2dp"
        android:background="@color/lightgrey" />

</LinearLayout>



</LinearLayout>

I honestly don't know what could be the problem. Maybe someone has eagle eyes to identify the error and help me solve it.

My Database Snapshot

Stack trace of the problem is as follows.

05-24 07:51:43.697 19173-19173/com.dreamlazerstudios.gtuconline E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.dreamlazerstudios.gtuconline, PID: 19173
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dreamlazerstudios.gtuconline/com.dreamlazerstudios.gtuconline.ChatActivity}: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2984)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
        at android.app.ActivityThread.-wrap14(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
     Caused by: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
        at com.google.firebase.database.DatabaseReference.child(Unknown Source)
        at com.dreamlazerstudios.gtuconline.ChatActivity.loadMessages(ChatActivity.java:121)
        at com.dreamlazerstudios.gtuconline.ChatActivity.onCreate(ChatActivity.java:67)
        at android.app.Activity.performCreate(Activity.java:6956)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045) 
        at android.app.ActivityThread.-wrap14(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 

This is the previous activity I am getting the string extra from

package com.dreamlazerstudios.gtuconline;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

import de.hdodenhof.circleimageview.CircleImageView;

import static android.content.ContentValues.TAG;

public class StudentsList extends AppCompatActivity {

DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<DataSnapshot> listData;
RecyclerView recyclerView;
StudentsList.MyAdapter adapter;

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private FirebaseDatabase mFirebaseDatabase;
private String userID;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_students_list);
    setTitle("List of Students");

    recyclerView = findViewById(R.id.students_list);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    listData = new ArrayList<>();
    adapter = new StudentsList.MyAdapter(listData);
    adapter.setHasStableIds(true);

    GetDataFirebase();

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading Data...");
    progressDialog.show();

    mAuth = FirebaseAuth.getInstance();
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef = mFirebaseDatabase.getReference();
    final FirebaseUser user = mAuth.getCurrentUser();
    userID = user.getUid();

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                // User is signed in

                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
            } else {
                // User is signed out
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
            // ...
        }
    };

}

void GetDataFirebase() {

    databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child("Students");

    databaseReference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            Students students = dataSnapshot.getValue(Students.class);

            listData.add(dataSnapshot);

            recyclerView.setAdapter(adapter);

            progressDialog.dismiss();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


}

@Override
public void onStart() {
    super.onStart();

    mAuth.addAuthStateListener(mAuthListener);

}

public class MyAdapter extends RecyclerView.Adapter<StudentsList.MyAdapter.ViewHolder> {

    List<DataSnapshot> list;

    public MyAdapter(List<DataSnapshot> List) {
        this.list = List;
    }

    @Override
    public void onBindViewHolder(final StudentsList.MyAdapter.ViewHolder holder, final int position) {

        final DataSnapshot studentSnapshot = list.get(position);

        final Students students = studentSnapshot.getValue(Students.class);

        final String list_user_id = studentSnapshot.getKey();

        holder.news_topic.setText(students.getName());
        holder.news_body.setText(students.getProgramme());

        if (students.getOnline() == true) {
            holder.online.setVisibility(View.VISIBLE);
        } else {
            holder.online.setVisibility(View.INVISIBLE);
        }

        Picasso.with(holder.news_image.getContext()).load(students.getThumb_image()).placeholder(R.drawable.student_icon_17870).into(holder.news_image);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent chat_intent = new Intent(StudentsList.this, ChatActivity.class);
                chat_intent.putExtra("user_id", list_user_id);
                chat_intent.putExtra("user_name", students.getName());
                startActivity(chat_intent);
            }
        });

    }

    @NonNull
    @Override
    public StudentsList.MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_list_layout, parent, false);

        return new StudentsList.MyAdapter.ViewHolder(view);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView news_topic, news_body;
        CircleImageView news_image;
        ImageView online;

        public ViewHolder(View itemView) {
            super(itemView);

            news_topic = itemView.findViewById(R.id.user_single_name);
            news_body = itemView.findViewById(R.id.user_single_status);
            news_image = itemView.findViewById(R.id.user_single_image);
            online = itemView.findViewById(R.id.online_status_icon);

        }

    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}
}
  • 1
    Hello, welcome to stack overflow. Please spare 5 minutes of your time to take the [tour](https://stackoverflow.com/tour) to see how to ask a productive question here in this community. In your case, the problems seems to be easily traceable by referring to the stack trace of when the exception is thrown.. – Romeo Sierra May 24 '18 at 08:11
  • I did check the stack trace. And it was still difficult to find the error. –  May 24 '18 at 08:14
  • Can you post it here? – Romeo Sierra May 24 '18 at 08:15
  • I have posted it –  May 24 '18 at 08:20
  • `at com.dreamlazerstudios.gtuconline.ChatActivity.loadMessages(ChatActivity.java:121)` and `at com.dreamlazerstudios.gtuconline.ChatActivity.onCreate(ChatActivity.java:67)` gives you the necessary information isn't it? So line numbers 67 and 121 of your `ChatActivity` seem to be problematic.. – Romeo Sierra May 24 '18 at 08:24
  • Yes Romeo. I checked all those. And proceeded to check the loadMessages method as it stated. And still found nothing. Wasted about 11 hours. –  May 24 '18 at 08:27
  • Judging by the situation, it seems like `mChatUser = getIntent().getStringExtra("user_id");` is not setting the value as you expect. It appears like you are passing some extras from a previous activity. However, there doesn't seem to have a value with the key `user_id`. That's the only possibility I can see here... – Romeo Sierra May 24 '18 at 08:30
  • How do I fix that? Any solution? –  May 24 '18 at 08:35
  • Is that the problem? – Romeo Sierra May 24 '18 at 08:37
  • If that's the line that is causing the error, then let's fix every possible cause of the crash. –  May 24 '18 at 08:39
  • You just can't blindly change the code and see if that works right? That's coding like hell! Try to debug the code with some breakpoints and see if that is the cause of the problem for sure. If we can verify that it is the problem, then we can discuss the solution.. – Romeo Sierra May 24 '18 at 08:44
  • @GabrielHagan your problem seems to be that `mChatUser` is `null` at the first line of the method `loadMessage()` when you do `child(mChatUser)`. As mentionned by Romeo, this is surely because there is no String extra having `"user_id"` as ID. Where do you put this string extra in your intent ? – vincrichaud May 24 '18 at 08:47
  • After debugging, I realised the userID and mChatUser are null. But I dont get why they would be null. Any way around this? –  May 24 '18 at 08:54
  • @vincrichaud I get it from the previous activity. So I don't get why it would be null –  May 24 '18 at 08:55
  • I have added the previous activity codes to make things clearer. –  May 24 '18 at 09:03
  • Anyone seen anything? –  May 24 '18 at 09:20

0 Answers0