【问题标题】:How to keep track of listeners in Firebase on Android?如何在 Android 上的 Firebase 中跟踪听众?
【发布时间】:2015-11-18 09:29:33
【问题描述】:

我有一个给定用户在一个位置的聊天室列表,以及给定聊天室在另一个位置的消息总数。我想跟踪用户所属聊天室中的一些消息。

我有以下sn-p:

//getting all chat rooms this user belongs to
mFirebase.child("myChatRooms").child("testUser").addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded (DataSnapshot dataSnapshot, String previousKey){
        for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
            ChatRoom myRoom = postSnapshot.getValue(ChatRoom.class);

            //listening to  message count in every chat room user belongs to
            mFirebase.child("chatRoomMessageCount").child(postSnapshot.getKey()).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                        //number of messages have changed
                }

                @Override
                public void onCancelled(FirebaseError firebaseError) {

                }
            });
        }
    }

    //......
}

问题是,我以后如何删除所有那些 ValueEventListener,什么时候会调用 onChildRemoved,或者我不再需要它们?

处理这种情况的推荐方法是什么?我应该将子键和侦听器存储在 HashMap 中并自己跟踪它们,还是有某种方法可以删除给定 firebase 位置的所有侦听器?

【问题讨论】:

    标签: java android firebase


    【解决方案1】:

    一种数据谨慎的方法是创建一个HashMapValueEventListeners,然后在onStoponDestroy 中删除这些侦听器。

    为简单起见,您应该使用单个事件侦听器来获取房间。然后,您可以为每个房间创建一个实时监听器。

    public class MainActivity extends Activity {
    
        private Firebase mRef;
        private HashMap<Firebase, ValueEventListener> mListenerMap;
    
        @Override
        protected void onStart() {
            super.onStart();
    
            mRef = new Firebase("https://<your-firebase-app>/myChatRooms/testUser");
    
            mRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
    
                        ValueEventListener listener = new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                // do your thing here
                            }
    
                            @Override
                            public void onCancelled(FirebaseError firebaseError) {
    
                            }
                        };
                        mListenerMap.put(postSnapshot.getRef(), listener);
                        Firebase childRef = mRef.child("chatRoomMessageCount").child(postSnapshot.getKey());
                        childRef.addValueEventListener(listener);
                    }
                }
    
                @Override
                public void onCancelled(FirebaseError firebaseError) {
    
                }
            });
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            for (Map.Entry<Firebase, ValueEventListener> entry : mListenerMap.entrySet()) {
                Firebase ref = entry.getKey();
                ValueEventListener listener = entry.getValue();
                ref.removeEventListener(listener);
            }
        }
    }
    

    【讨论】:

    • 这基本上就是我的想法。我真的希望有一种更优雅的方式来做到这一点,或者已经内置了类似的功能。例如,我们可以将 TAG 作为第二个参数传递给 addValueEventListener,然后调用 removeValueEventListenersWithTag 之类的东西。但是,我想考虑到 firebase 的实时性和连续性,你们决定把它留给开发人员,这没关系,但你必须在文档中反映它。扁平数据通常会导致嵌套的侦听器,这可能会让刚接触这个概念的人感到困惑。
    • 我同意。我将对更优雅的解决方案进行更多研究。非常感谢您的反馈!
    • 这是否符合您接受的答案的要求?还是有其他考虑?
    • @Lion789 是的!无需删除 SingleEventListener,因为它们会在数据首次下载后自行删除。
    • HashMap 需要在put 方法起作用之前被初始化。否则将抛出 NullPointerException。 private HashMap&lt;Firebase, ValueEventListener&gt; mListenerMap; 行应更新为 private HashMap&lt;Firebase, ValueEventListener&gt; mListenerMap = new HashMap&lt;Firebase, ValueEventListener&gt;();
    猜你喜欢
    • 2013-03-05
    • 2019-09-26
    • 2019-06-09
    • 2017-12-25
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    相关资源
    最近更新 更多