ANDROID Firebase addChildEventListener

时间:2019-02-21 18:11:01

标签: java android database firebase firebase-realtime-database

我对函数“ 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

我注意到,如果我去另一个片段然后很快回来,问题就不会出现。

我的应用程序其他部分也存在相同的问题,在这种情况下,我使用AddValueEventListener,如果我删除列表中的一个元素,然后再添加另一个元素,则删除的元素会与加了一个。

我可以告诉您这不是数据库中的问题,因为如果我仅关闭应用程序然后再次启动,则会显示出良好的数据。因此,正在检索数据。

我可以使用一些for循环解决所有这些问题,但我认为这不是好方法。

3 个答案:

答案 0 :(得分:0)

我只需调用displaymessage即可解决

@Overrride

@Override
    public void onResume() {
        super.onResume();
        loadData();
    }

答案 1 :(得分:0)

以下是调用该片段的活动代码:

公共类Main2Activity扩展了MenuInsideEvent {

private Toolbar mToolbar;
private FragmentPagerAdapter fragmentadaptater2;
private ViewPager mviewpager;      //view pager sert a afficher  les fragments! DANS LE activity_main .XML on l'a mise en dessous ( below) de la toolbar que l' on a inclu
private TabLayout mtablayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mviewpager = (ViewPager) findViewById(R.id.main_tabs_pager);
    mToolbar = (Toolbar) findViewById(R.id.main_page_toolbar);
    mtablayout = (TabLayout) findViewById(R.id.main_tabs);

    setSupportActionBar(mToolbar);
    getSupportActionBar().setTitle("SocialGroup");

    SetActionBar();



    fragmentadaptater2 = new FragmentAdaptater2(getSupportFragmentManager());
    mviewpager.setAdapter(fragmentadaptater2);
    mtablayout = (TabLayout) findViewById(R.id.main_tabs);
    mtablayout.setupWithViewPager(mviewpager);


}

@Override
public void onBackPressed() {


    SendUserToMainActivity();
    super.onBackPressed();
}

public void SetActionBar ()
{
    ActionBar ab = getSupportActionBar();

    ab.setTitle(getsGroupName());
    ab.setSubtitle("MyApp");
}
private void SendUserToMainActivity()
{
    Intent intent = new Intent(Main2Activity.this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(intent);
    finish();

}

}

片段代码与我在帖子中发布的相同。 除了我有: @Override     公共无效onResume(){

    retrievedata();
    super.onResume();
}

,然后从视图中删除了retrievedata()。

答案 2 :(得分:-1)

为什么发生这种情况,是因为每次应用程序oncreate都被称为再次调用的片段,但该片段并不一定是 所以暂停 去除碎片 并添加回去 在恢复或开始时 您可以发送片段代码吗?