Я пытаюсь показать сообщения между двумя пользователями в окне просмотра. Все идет хорошо до тех пор, пока я не перезапущу действие на обоих устройствах, и при перезапуске действия добавляется дочерний прослушиватель событий, и я вижу несколько сообщений вместо одного, которое я отправил, и когда я перезапускаю свою активность без отправки какого-либо сообщения, он показывает мне исходное количество сообщений, и если я снова отправляю или получаю сообщение, я вижу несколько сообщений и цикл повторяется. Я пытался удалить слушателя в onDestroy и onStop, но безрезультатно.
Код
MessageActivity. java (обновлено)
public class MessageActivity extends AppCompatActivity {
CircleImageView profile_image;
TextView user_name;
FirebaseFirestore fstore;
FirebaseAuth fAuth;
FirebaseUser fuser;
DatabaseReference reference;
ChildEventListener mChildEventListener;
ValueEventListener mValueEventListener;
Toolbar toolbar;
ImageButton imageButton;
EditText textsend;
String userID;
MessageAdapter messageAdapter;
List<Chat> mChat;
RecyclerView recyclerView;
DatabaseReference Chatreference;
String TAG = "MyTag";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
fAuth = FirebaseAuth.getInstance();
fstore = FirebaseFirestore.getInstance();
userID = fAuth.getCurrentUser().getUid();
profile_image = findViewById(R.id.profile_image);
user_name = findViewById(R.id.username);
imageButton = findViewById(R.id.btn_send);
textsend = findViewById(R.id.text_send);
recyclerView = findViewById(R.id.recycler_view2);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
toolbar = findViewById(R.id.myToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Intent intent = getIntent();
fuser = FirebaseAuth.getInstance().getCurrentUser();
String userid = intent.getStringExtra("userid");
//String username = intent.getStringExtra("UserName");
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
mValueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
user_name.setText(user.getFirst());
Log.d(TAG, "Value Event Listener called");
if (user.getImageURL().equals("default")) {
profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
//and this
Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
}
readMessages(fuser.getUid(), userid, user.getImageURL());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
reference.addValueEventListener(mValueEventListener);
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = textsend.getText().toString();
textsend.setText("");
if (!msg.equals("")) {
sendMessage(fuser.getUid(), userid, msg);
} else {
Toast.makeText(MessageActivity.this, "Empty messages cant be send", Toast.LENGTH_SHORT).show();
}
}
});
}
private void sendMessage(String sender, final String receiver, String message) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
DatabaseReference Chatreference = FirebaseDatabase.getInstance().getReference("Chats");
String key = Chatreference.push().getKey();
Chatreference.child(key).setValue(hashMap);
}
private void readMessages(String myid, String userid, String imageurl) {
mChat = new ArrayList<>();
Chatreference = FirebaseDatabase.getInstance().getReference("Chats");
mChildEventListener = new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Chat chat = dataSnapshot.getValue(Chat.class);
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) {
chat.setMessageId(dataSnapshot.getKey());
mChat.add(chat);
Log.d(TAG, "Child_Event_Listener_Called");
Log.d(TAG, "msg " + chat.getMessage());
}
Log.d(TAG, "msg " + chat.getMessage());
messageAdapter = new MessageAdapter(MessageActivity.this, mChat, imageurl);
recyclerView.setAdapter(messageAdapter);
messageAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Chat chat = dataSnapshot.getValue(Chat.class);
chat.setMessageId(dataSnapshot.getKey());
mChat.remove(chat);
messageAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
Chatreference.addChildEventListener(mChildEventListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
Chatreference.removeEventListener(mChildEventListener);
}
}
MessageAdapter. java
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
private Context mContext;
private List<Chat> mChat;
String imageurl;
FirebaseUser fuser;
public MessageAdapter(Context mContext, List<Chat> mChat,String imageurl) {
this.mContext = mContext;
this.mChat = mChat;
this.imageurl=imageurl;
}
@NonNull
@Override
public MessageAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
return new MessageAdapter.ViewHolder(view);
}
else {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
return new MessageAdapter.ViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull MessageAdapter.ViewHolder holder, int position) {
Chat chat=mChat.get(position);
holder.show_message.setText(chat.getMessage());
if (imageurl.equals("default")){
holder.profile_image.setImageResource(R.mipmap.ic_launcher);
} else {
Glide.with(mContext).load(imageurl).into(holder.profile_image);
}
holder.show_message.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
String message_id=chat.getMessageId();
Task<Void> task = Utils.removeUser(message_id);
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(mContext,"Message Deleted",Toast.LENGTH_SHORT).show();
}
});
return true;
}
});
}
@Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView show_message;
public ImageView profile_image;
public ViewHolder(@NonNull View itemView) {
super(itemView);
show_message=itemView.findViewById(R.id.show_message);
profile_image=itemView.findViewById(R.id.profile_image);
}
}
@Override
public int getItemViewType(int position) {
fuser= FirebaseAuth.getInstance().getCurrentUser();
if (mChat.get(position).getSender().equals(fuser.getUid())){
return MSG_TYPE_RIGHT;
}
else {
return MSG_TYPE_LEFT;
}
}
}
Чат. java
public class Chat {
private String sender;
private String receiver;
private String message;
String MessageId;
public Chat(String sender, String receiver, String message) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
}
public Chat() {
}
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;
}
@Override
public boolean equals(@Nullable Object obj) {
if(obj instanceof Chat){
Chat chat=(Chat) obj;
return this.MessageId.equals(chat.getMessageId());}
else
return false;
}
}