2016-08-21 71 views
2

當我向列表視圖添加新消息時,添加了我擁有的消息和新消息,因此它將兩次放置相同的信息。Firebase中的重複對象加載到ListView中

我想在火力地堡列表視圖加載最後一封郵件,我有如下功能爲創建():

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

而對於增加新的消息:

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

     } 


    } 
}); 
+0

是啊!準備好了 –

回答

4

當您使用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()); 
    } 
}); 

如果你使用這種方法,首先你onChildAdded()將被調用3次,一次爲每個項目。然後,當您添加第4個孩子時,onChildAdded()將再次調用只是第4個項目

0

你不應該除了通過Firebase監聽器之外,還可以添加其他任何方式的消息,但我想在發送消息後,您會在mCDataAdatapter.add(message.getText().toString());處執行此操作。原因是,即使在發送新消息的客戶端,Firebase也會自動呼叫onDataChange

我也推薦使用ChildEventListener,否則你應該清除整個ListView或過濾更改以避免相同的數據。你在做嗎?