2016-08-21 3 views
2

新しいメッセージをlistviewに追加すると、自分が持っているメッセージと新しいメッセージが追加されるので、同じ情報が2回表示されます。私はFirebaseとリストビュー内の最後のメッセージを読み込みたい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メッセージで呼び出されます。あなたはその後、第四のメッセージを追加する場合:

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番目の子を追加すると、の4番目の項目だけでonChildAdded()が再度呼び出されます。

0

あなたはいけませんFirebaseのリスナー以外の方法でメッセージを追加することもできますが、メッセージを送信した後はmCDataAdatapter.add(message.getText().toString());という行でそれをやっていると思います。その理由は、新しいメッセージを送信したクライアントにも新しいメッセージを追加すると、Firebaseは自動的にonDataChangeを呼び出します。

ChildEventListenerを使用することをお勧めします。それ以外の場合は、ListView全体を消去するか、同じデータを避けるために変更をフィルタする必要があります。あなたはそれをやっていますか?

関連する問題