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

Android 从Firebase加载到ListView的重复对象,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,当我向listview添加新消息时,会添加我拥有的消息和新消息,因此它会将相同的信息放两次 我想用Firebase加载listview中的最后一条消息,我在create()中有以下函数: firebase=newfirebase(firebase\u URL).child(firebase\u child+“/”+SharedReferences.getString(“chatKey”,null).toString()+“/room/”; firebase.child(“messages”).a

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

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

firebase=newfirebase(firebase\u URL).child(firebase\u child+“/”+SharedReferences.getString(“chatKey”,null).toString()+“/room/”;
firebase.child(“messages”).addValueEventListener(新的ValueEventListener(){
@凌驾
公共无效onDataChange(数据快照快照){
if(Snapshot.getValue()!=null){
Iterable迭代器=Snapshot.getChildren();
itemMessage itemData;
for(DataSnapshot值:迭代器){
itemData=value.getValue(itemMessage.class);
添加(itemData.getMessage().toString());
}
mConversation.setAdapter(mcdata适配器);
}
}
对于添加新消息:

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("");

        }


    }
});
sendMessage.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
SharedReferences SharedReferences=PreferenceManager.getDefaultSharedReferences(ChatActivity.this);
SharedReferences.Editor=SharedReferences.edit();
//editor.clear().commit();
if(sharedReferences.getString(“chatKey”,null)!=null&&sharedReferences.getString(“chatKey,null”).toString()!=“”){
messageLevel=新Firebase(Firebase\u URL+共享引用
.getString(“聊天键”,null)
.toString()+“/room/”)
.儿童(“信息”);
Map messageData=newhashmap();
messageData.put(“message”,message.getText().toString());
messageData.put(“userTo”,1);
messageData.put(“userFrom”,2);
消息级别
.push()
.setValue(messageData);
添加(message.getText().toString());
mConversation.setAdapter(mcdata适配器);
message.setText(“”);
}
}
});

除了通过Firebase listener之外,您不应该以任何其他方式添加消息,但我猜您是在发送消息后在第
行mCDataAdatapter.add(message.getText().toString());
中添加消息。原因是Firebase在添加新消息时会自动调用
onDataChange


我还建议您使用
ChildEventListener
,否则您应该清除整个
ListView
或过滤更改以避免相同的数据。您正在这样做吗?

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

message 1
message 2
message 3
您的
onDataChange()
将通过以下3条消息被调用。如果您随后添加第4条消息:

message 1
message 2
message 3
message 4
您的
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());
    }
});
如果使用此方法,最初将调用3次
onchildaded()
,每个项调用一次。然后,当添加第4个子项时,仅使用第4项再次调用
onchildaded()

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());
    }
});