如何在Firebase实时数据库中使用onChildRemoved?

时间:2018-08-25 15:18:38

标签: java android firebase firebase-realtime-database

好的,我想知道onChildRemoved在Firebase Realtime Databse中的工作方式。我可以在用户实时添加数据后立即添加数据。但是当用户删除数据时,我想做同样的事情。如何进行呢?我阅读了文档,但无法获取。

任何帮助将不胜感激。

PS:我可以通过mRootRef.child("message").removeValue(); 删除数据,但我必须返回并再次参加此活动以查看更改。

private void loadmessage(String class_id, String email_red) {
            messageQuery.addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                    Message message = dataSnapshot.getValue(Message.class);
                    messageList.add(message);
                    mAdapter.notifyDataSetChanged();
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {
                   //what to add here??
                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }

3 个答案:

答案 0 :(得分:3)

添加以下代码代替//what to add here??

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
    //what to add here??
    Message message = dataSnapshot.getValue(Message.class);
    messageList.remove(message);
    mAdapter.notifyDataSetChanged();
}

答案 1 :(得分:3)

@ mark922的答案具有要点,但是您还需要一些步骤。

从数据库中删除一条消息时,您将在DataSnapshot中获得该删除消息的onChildRemoved。您将需要:

  1. 在您的messageList中找到相应的消息。
  2. 从列表中删除邮件。
  3. 调用mAdapter.notifyDataSetChanged()以使适配器重新绘制列表/回收器视图。

棘手的是步骤1,因为这意味着您需要能够找到消息。最简单的方法是为每个消息保留DataSnapshot.getKey()。由于每个子节点的密钥必须唯一,因此保证每个密钥只有一条消息。

将其添加到当前代码中的一种简单方法是添加一个keyList

List<String> keyList = new ArrayList<String>();

然后将每个DataSnapshot的键添加到该列表,同时添加值t messageList

public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    Message message = dataSnapshot.getValue(Message.class);
    messageList.add(message);
    keyList.add(dataSnapshot.getKey());
    mAdapter.notifyDataSetChanged();
}

现在您有一个keyList和一个messageList,并且每个索引处的项目都彼此对应。因此,keyList[0]中的键对应于messageList[0]中的值,等等。

这意味着您可以在onChildRemoved中查找在keyList中删除的邮件的索引,然后根据以下信息从messageListkeyList中删除该邮件索引:

public void onChildRemoved(DataSnapshot dataSnapshot) {
    int index = keyList.indexOf(dataSnapshot.getKey());
    messageList.remove(index);
    keyList.remove(index);
    mAdapter.notifyDataSetChanged();
}

关于邮件插入的说明

以上代码仅在新消息始终附加在列表末尾时才有效。在一个简单的聊天应用中,这可能是正确的。但是在更先进的应用程序中,您也可以在列表中的其他位置插入数据。

在这种情况下,传递到String s的{​​{1}}变得很重要,因为它实际上是onChildAdded:子代之前的密钥,插入了孩子。为了正确处理此情况,您应该跟踪项目的顺序,例如,通过将键和值插入相应列表中的正确索引中。届时,您还需要处理String previousChildKey和(对此情况更重要)onChildChanged

所有这些都不是那么复杂,但是很容易出错。我建议您看看FirebaseArray class from FirebaseUI作为示例/灵感来源。

答案 2 :(得分:0)

将其添加到当前代码的一种简单方法是添加一个keyList:

List<String> keyList = new ArrayList<String>();

然后在将值添加到messageList时,将每个DataSnapshot的密钥添加到keyList中:

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
    String key = dataSnapshot.getKey();
    int index = keyList.indexOf(key);

    if (index != -1) {
        messageList.remove(index);
        keyList.remove(index);
    }
    mAdapter.notifyDataSetChanged();
}