У меня проблема с функцией "addChildEventListener". Я использую ее для группового чата.Я читаю все чаты из группы в базе данных и помещаю их в представление списка.
Вот контекст:
У меня есть действие с 3 фрагментами в нем
Вот проблема:
Если я захожу во фрагмент чата, все работает отлично: просмотр списка заполнен чатом, и все в порядке.
НО, если я перехожу к другому фрагментуи затем возвращаются в чат, по какой-то причине он возвращается в addChildEventListener и особенно в функцию "onChildAdded", и все сообщения чата пишутся во второй раз.
Если я перейду к другому фрагменту и вернусь снова, он сделает это снова.Я заметил ту же проблему, если заблокировать телефон (черный экран), когда я в приложении, а затем разблокировать его.
Вот код:
public class ChatFragment extends Fragment {
private ImageButton SendMessageButton;
private EditText userMessageInput;
private TextView displayMessageText;
private ScrollView mScrollView;
private String EventName;
private FirebaseAuth mAuth;
private DatabaseReference UserRef, GroupeNameReference, GroupMessageKeyRef;
View groupFragmentView;
private String currentGroupName, currentUserID, currentUserName, currentDateMessage, currentTimeMessage;
private ListView mListView;
private List <ChatClass> ListOfChats = new ArrayList<>();
ChatAdapter adapter;
CommunActivit obj = new CommunActivit();
public ChatFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
groupFragmentView = inflater.inflate(R.layout.fragment_chat, container, false);
mAuth=FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
UserRef= FirebaseDatabase.getInstance().getReference().child("Users");
GroupeNameReference = FirebaseDatabase.getInstance().getReference().child("Groups").child((obj.getsGroupID())).child("groupe_chat");
GetUserInfo(); //get the username
SendMessageButton=(ImageButton) groupFragmentView.findViewById(R.id.group_message_button);
userMessageInput=(EditText) groupFragmentView.findViewById(R.id.input_group_message);
mListView = (ListView) groupFragmentView.findViewById(R.id.List_of_chat);
SendMessageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendMessageToGroupChat();
userMessageInput.setText("");
}
});
adapter = new ChatAdapter(getContext() , ListOfChats);
mListView.setAdapter(adapter);
final ListViewAutoScrollHelper scrollHelper = new ListViewAutoScrollHelper(mListView);
scrollHelper.setEnabled(true);
mListView.setOnTouchListener(scrollHelper);
retrievedata();
return groupFragmentView;
}
private void GetUserInfo()
{
UserRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
currentUserName=dataSnapshot.child("name").getValue().toString();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
}
});
}
private void SendMessageToGroupChat()
{
String message = userMessageInput.getText().toString();
String messageKey = GroupeNameReference.push().getKey();
if(TextUtils.isEmpty(message))
{
Toast.makeText(getContext(), "Please write a message first", Toast.LENGTH_SHORT).show();
}
else
{
Calendar calendarDate = Calendar.getInstance();
SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy");
currentDateMessage = DateFormat.format(calendarDate.getTime());
Calendar calendarTime = Calendar.getInstance();
SimpleDateFormat TimeFormat = new SimpleDateFormat("hh:mm a");
currentTimeMessage = TimeFormat.format(calendarTime.getTime());
HashMap<String, Object> groupMessageKey = new HashMap<>();
GroupeNameReference.updateChildren(groupMessageKey);
GroupMessageKeyRef = GroupeNameReference.child(messageKey);
HashMap<String, Object> messageInfoMap = new HashMap<>();
messageInfoMap.put("name", currentUserName);
messageInfoMap.put("message", message);
messageInfoMap.put("date", currentDateMessage);
messageInfoMap.put("time", currentTimeMessage);
GroupMessageKeyRef.updateChildren(messageInfoMap);
}
}
public void retrievedata(){
GroupeNameReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) /**** HERE IS THE PROBLEM***/
{
if (dataSnapshot.exists())
{
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s)
{
if (dataSnapshot.exists())
{
DisplayMessages(dataSnapshot);
}
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void DisplayMessages(DataSnapshot dataSnapshot) /*****Essayer cette méthode pour afficher les groupes !******/
{
Iterator iterator = dataSnapshot.getChildren().iterator();
while (iterator.hasNext())
{
String chatDate = (String) ((DataSnapshot)iterator.next()).getValue();
String chatMessage = (String) ((DataSnapshot)iterator.next()).getValue();
String chatName = (String) ((DataSnapshot)iterator.next()).getValue();
String chatTime = (String) ((DataSnapshot)iterator.next()).getValue();
ListOfChats.add(new ChatClass(chatName,chatMessage, chatDate + " "+chatTime,""));
adapter.notifyDataSetChanged();
}
}
}
![enter image description here](https://i.stack.imgur.com/IAtla.png)
Я заметил, что если я перейду к другому фрагменту и вернусь очень быстро, проблема не появится.
У меня естьТо же самое происходит с другой частью моего приложения, в этом случае я использую AddValueEventListener, и если я удаляю элемент списка, то добавляю другой элемент сразу после этого, удаленный возвращается вместе с добавленным.
Я могу вам сказать, что это не проблема в базе данных, потому что, если я просто закрою приложение и снова запуском, хорошие данные будут показаны.Так что в процессе извлечения данных.
Я мог бы решить все это с помощью нескольких циклов for, но я думаю, что это не очень хороший способ.