从Firebase加载到ListView中的重复对象

Mil*_*era 2 android firebase firebase-realtime-database

当我向listview添加新消息时,会添加我拥有的消息和新消息,因此它会将相同的信息放两次.

我想在使用Firebase的listview中加载最后一条消息,我在create()中有以下函数:

firebase = new Firebase(FIREBASE_URL).child(FIREBASE_CHILD + "/" + sharedPreferences.getString("chatKey", null).toString() + "/room/");

firebase.child("messages").addValueEventListener(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot Snapshot) {

        if (Snapshot.getValue() != null) {
            Iterable<DataSnapshot> iterator = Snapshot.getChildren();
            itemMessage itemData;

            for(DataSnapshot value : iterator){
                itemData = value.getValue( itemMessage.class );
                mCDataAdatapter.add( itemData.getMessage().toString() );
            }

           mConversation.setAdapter( mCDataAdatapter );
        }
    }
Run Code Online (Sandbox Code Playgroud)

并添加新消息:

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

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ChatActivity.this);

        SharedPreferences.Editor editor = sharedPreferences.edit();

       // editor.clear().commit();

        if( sharedPreferences.getString("chatKey", null) != null && sharedPreferences.getString("chatKey", null).toString() != "" ){

            messageLevel = new Firebase(FIREBASE_URL+sharedPreferences
                    .getString("chatKey", null)
                    .toString()+"/room/")
                    .child("messages");

            Map<String, Object> messageData = new HashMap<String, Object>();
            messageData.put( "message", message.getText().toString() );
            messageData.put( "userTo", 1 );
            messageData.put( "userFrom",2 );
            messageLevel
                    .push()
                    .setValue(messageData);

            mCDataAdatapter.add( message.getText().toString() );

            mConversation.setAdapter( mCDataAdatapter );

            message.setText("");

        }


    }
});
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 5

使用时addValueEventListener(),将立即使用节点的当前值调用处理程序,并在每次节点的值更改时调用.每次调用处理程序时,它都会获取您侦听的整个内容的快照.所以如果你从3条消息开始

message 1
message 2
message 3
Run Code Online (Sandbox Code Playgroud)

onDataChange()将使用这3条消息调用.如果您然后添加第4条消息:

message 1
message 2
message 3
message 4
Run Code Online (Sandbox Code Playgroud)

onDataChange()将使用所有4条消息调用.如果您坚持使用当前代码,则必须自己检测并删除重复项.

幸运的是,Firebase SDK还允许您通过调用来监听级别的更改addChildEventListener().从链接的文档:

ref.addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());

        // A new comment has been added, add it to the displayed list
        Comment comment = dataSnapshot.getValue(Comment.class);
    }

    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so displayed the changed comment.
        Comment newComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();
    }

    public void onChildRemoved(DataSnapshot dataSnapshot) {
        Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());

        // A comment has changed, use the key to determine if we are displaying this
        // comment and if so remove it.
        String commentKey = dataSnapshot.getKey();
    }

    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
        Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());

        // A comment has changed position, use the key to determine if we are
        // displaying this comment and if so move it.
        Comment movedComment = dataSnapshot.getValue(Comment.class);
        String commentKey = dataSnapshot.getKey();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.w(TAG, "postComments:onCancelled", databaseError.toException());
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您使用这种方法,最初您onChildAdded()将被调用3次,每个项目一次.然后,当您添加第4个子项时,onChildAdded()仅使用第4个项目再次调用.