So I am making an android messaging app in java with firebase phone authentication and realtime database.I am trying to add read or unread status on the last sent message using this tutorial.I wrote this code :
private void seenMessage(final String userid){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("chats").child(senderRoom).child("messages");
// reference.keepSynced(true);
seenListener=reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if(snapshot.exists()) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Message chat = snapshot.getValue(Message.class);
Toast.makeText(ChatActivity.this, chat.getMessage(), Toast.LENGTH_SHORT).show();
if (chat.getReceiver().equals(FirebaseAuth.getInstance().getCurrentUser().getUid().toString()) && chat.getSender().equals(userid.toString())) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("isseen", true);
Toast.makeText(ChatActivity.this, dataSnapshot.getRef().toString(), Toast.LENGTH_SHORT).show();
dataSnapshot.getRef().updateChildren(hashMap);
}
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
reference.addListenerForSingleValueEvent(seenListener);
}
and I am calling it here:
ActivityChatBinding binding;
MessagesAdapter adapter;
ArrayList<Message> messages;
String senderRoom, receiverRoom;
FirebaseDatabase database;
AlertDialog alertDialog;
ValueEventListener seenListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityChatBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
showProgressBar("Loading messages...");
messages = new ArrayList<>();
adapter = new MessagesAdapter(this, messages);
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
binding.recyclerView.setAdapter(adapter);
String name = getIntent().getStringExtra("name");
String senderUid = FirebaseAuth.getInstance().getUid();
String receiverUid = getIntent().getStringExtra("uid");
senderRoom = senderUid + receiverUid;
receiverRoom = receiverUid + senderUid;
if(!isNetworkConnected()){
noInternetDialog();
} else {
database = FirebaseDatabase.getInstance();
database.getReference().child("chats")
.child(senderRoom)
.child("messages")
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
messages.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
Message message = snapshot1.getValue(Message.class);
messages.add(message);
}
adapter.notifyDataSetChanged();
binding.recyclerView.scrollToPosition(messages.size() - 1);
hideProgressBar();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
hideProgressBar();
Toast.makeText(ChatActivity.this, "Something went wrong!.", Toast.LENGTH_SHORT).show();
}
});
seenMessage(senderUid);
}
This is my message class:
package net.bestie.Models;
public class Message {
private String sender;
private String receiver;
private String message;
private boolean isseen;
private long timestamp;
String MessageId;
public Message(String sender, String receiver, String message, boolean isseen, long timestamp) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
this.isseen = isseen;
this.timestamp = timestamp;
}
public Message() {
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessageId() {
return MessageId;
}
public void setMessageId(String messageId) {
MessageId = messageId;
}
public boolean isIsseen() {
return isseen;
}
public void setIsseen(boolean isseen) {
this.isseen = isseen;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
And in my messages Adapter:
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Message message = messages.get(position);
boolean isSeen= message.isIsseen();
if (holder.getClass() == SentViewHolder.class) {
SentViewHolder viewHolder = (SentViewHolder) holder;
viewHolder.binding.message.setText(message.getMessage());
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
viewHolder.binding.messageTime.setText(dateFormat.format(new Date(message.getTimestamp())));
if(position == messages.size() -1) {
if (isSeen) {
viewHolder.binding.messageStatus.setText("Read");
} else {
viewHolder.binding.messageStatus.setText("Delivered");
}
}
} else {
ReceiveViewHolder viewHolder = (ReceiveViewHolder) holder;
viewHolder.binding.message.setText(message.getMessage());
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
viewHolder.binding.messageTeam.setText(dateFormat.format(new Date(message.getTimestamp())));
}
}
It is not updating in firebase database or app.And when I open a user it crashes with this error:
E/net.bestie: [qarth_debug:] get PatchStore::createDisableExceptionQarthFile method fail.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: net.bestie, PID: 5201
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at net.bestie.Activities.ChatActivity$3.onDataChange(ChatActivity.java:155)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
I/Process: Sending signal. PID: 5201 SIG: 9
My Firebase database Strucuture
Any help will be Appreciated. :)