如何设置addSnapshotListener并在RecyclerView Item中的populateViewHolder中删除?

Pan*_*iya 2 java android firebase firebaseui google-cloud-firestore

我已经RecyclerViewFirebaseUI-Android库实现了。

RecyclerView一旦使用,我的实时数据就会发生变化FirebaseRecyclerAdapter

在Collection中,数据文档的字段类型为Boolean,Integer,Reference

想使用该参考获取数据populateViewHolderaddSnapshotListener

帮我!这是我的代码:

         FirebaseRecyclerAdapter<Conv, ConvViewHolder> firebaseConvAdapter = new FirebaseRecyclerAdapter<Conv, ConvViewHolder>(
            Conv.class,
            R.layout.users_single_layout,
            ConvViewHolder.class,
            conversationQuery
    ) {
        @Override
        protected void populateViewHolder(final ConvViewHolder convViewHolder, final Conv conv, int i) {

            final String list_user_id = getRef(i).getKey();

            final DocumentReference docRef = db.collection("cities").document(list_user_id);
            docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
                @Override
                public void onEvent(@Nullable DocumentSnapshot snapshot,
                                    @Nullable FirebaseFirestoreException e) {
                    if (e != null) {
                        Log.w(TAG, "Listen failed.", e);
                        return;
                    }

                    if (snapshot != null && snapshot.exists()) {
                        Log.d(TAG, "Current data: " + snapshot.getData());
                    } else {
                        Log.d(TAG, "Current data: null");
                    }
                }
            });
        }
    };

    mConvList.setAdapter(firebaseConvAdapter);
Run Code Online (Sandbox Code Playgroud)

Firebase说,如果您添加addSnapshotListener,则必须将其删除一次,而不需要分离侦听器

当您不再对侦听数据感兴趣时,必须分离侦听器,以使事件回调不再被调用。这允许客户端停止使用带宽来接收更新。您可以使用取消订阅功能onSnapshot()停止监听更新。

Ale*_*amo 5

为此,您需要使用EventListener<DocumentSnapshot>如下代码:

EventListener<DocumentSnapshot> eventListener = new EventListener<DocumentSnapshot>() {
    @Override
    public void onEvent(DocumentSnapshot snapshot, FirebaseFirestoreException e) {
        if (snapshot != null && snapshot.exists()) {
            //Do what you need to do
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

声明一个全局ListenerRegistration listenerRegistration;变量,然后在需要的地方添加SnapshotListener,如下所示:

if (listenerRegistration == null ) {
    listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
Run Code Online (Sandbox Code Playgroud)

要删除侦听器,只需在您的onStop()方法中使用以下代码行:

@Override
protected void onStop() {
    if (listenerRegistration != null) {
        listenerRegistration.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)

同样,一旦您的onStart()方法被调用,不要忘记再次添加它。

@Override
protected void onStart() {
    super.onStart();
    listenerRegistration = yourRef.addSnapshotListener(eventListener);
}
Run Code Online (Sandbox Code Playgroud)

当你打电话addSnapshotListener听实时更新,这意味着您可以将被调用为每一个发生在你的数据库更改侦听器。因此,当您关闭应用程序时也会发生这种情况,这就是为什么必须在活动被销毁之前分离侦听器的原因。

如果您不需要在应用程序中实时获取数据,则可以直接在引用上直接使用get()调用,该引用仅读取一次文档。由于它仅读取一次,因此没有要删除的侦听器。这是addListenerForSingleValueEvent()Firebase实时数据库中使用的通讯对象。

还有一种删除监听器的更优雅的方法,该方法是将活动作为addSnapshotListener()方法中的第一个参数传递,因此Firestore可以在活动停止时自动清理监听器。

ListenerRegistration lg = yourDocumentRef
            .addSnapshotListener(YourActivity.this, eventListener);
Run Code Online (Sandbox Code Playgroud)