Зная, когда Firebase завершил вызов API?

У меня возникли проблемы с пониманием того, когда мой вызов API Firebase завершен. После чтения Firebase documentation я нашел следующее:

События события всегда запускаются последними и гарантированно содержат обновления от любых других событий, которые произошли до того, как был сделан снимок.

Я понимаю, это означает, что только после завершения вызова onChildAdded вызывается ValueEventListener. В результате я подумал, что могу заполнить свой RecyclerView в функции onChildAdded, а затем вызов onSingleValueListener, я могу просто закончить анимацию моего экрана загрузки (который начал анимацию перед этим вызовом функции) и продолжить. Однако я столкнулся с проблемой, когда я поставил несколько осторожных операторов System.out.println и обнаружил, что в моем случае Test 1 вызывается до вызова Test 2. Это вызывает проблемы, потому что это фактически противоположное поведение того, что я хотел: я хотел, чтобы функция onChildAdded закончила, а затем вызвала функцию onSingleValueListener, которая выводит Test 1 для вызова. Есть ли причина, почему это происходит? Как это обойти? Я был бы признателен за объяснение, почему это происходит. Спасибо!

public void getComments(final String postId, final Activity activity, final View fragmentView, final View progressOverlay) {
    final Firebase commentsRef = firebaseRef.child("/comments");
    Firebase linkRef = firebaseRef.child("/posts/" + postId);
    linkRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            System.out.println("Test 1");
            if (progressOverlay.getVisibility() == View.VISIBLE) {
                progressOverlay.setVisibility(View.GONE);
                AndroidUtils.animateView(progressOverlay, View.GONE, 0, 200);
                fragmentView.findViewById(R.id.rv_view_comments).setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
    linkRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            commentsRef.child(dataSnapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    Comment comment = dataSnapshot.getValue(Comment.class);
                    System.out.println("Test 2");
                    application.getCommentsRecyclerViewAdapter().getCommentsList().add(comment);
                    application.getCommentsRecyclerViewAdapter().notifyDataSetChanged();
                }

                @Override
                public void onCancelled(FirebaseError firebaseError) {

                }
            });
        }

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

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

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

        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
} 

Ответ 1

С помощью этого кода "Firebase linkRef = firebaseRef.child("/posts/" + postId);" я мог видеть, что вы используете устаревший API Firebase. Теперь он устарел!

Просьба обновить свой код до нового API Firebase 3.x.x.

Ниже два независимых асинхронных вызова; На основе вашего прецедента вы можете использовать один из слушателей для чтения ваших данных.

1. linkRef.addListenerForSingleValueEvent(new ValueEventListener() {});
2. linkRef.addChildEventListener(new ChildEventListener() {});

Вы можете обратиться к документу firebase, чтобы получить дополнительную информацию о прослушивателях базы данных. https://firebase.google.com/docs/database/android/retrieve-data

С помощью следующего фрагмента кода вы можете получить и заполнить список комментариев.

public void getComments(final String postId, final Activity activity, final View fragmentView, final View progressOverlay) {
    DatabaseReference commentsRef = firebaseRef.child("/comments");
    DatabaseReference linkRef = commentsRef.child("/posts/" + postId);
    linkRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // Iterate through data-snapshot, and update your Adapter dataset
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Comment comment = snapshot.getValue(Comment.class);
                application.getCommentsRecyclerViewAdapter().getCommentsList().add(comment);
            }
            application.getCommentsRecyclerViewAdapter().notifyDataSetChanged();

            // Dismiss your loading progressbar
            if (progressOverlay.getVisibility() == View.VISIBLE) {
                progressOverlay.setVisibility(View.GONE);
                AndroidUtils.animateView(progressOverlay, View.GONE, 0, 200);
                fragmentView.findViewById(R.id.rv_view_comments).setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Handle fail case here
        }
    });

Надеюсь, это поможет вам!

Ответ 2

Вы можете использовать класс **FirebaseRecyclerAdapter**, который команда Firebase предоставляет в FirebaseUI-Android (см. https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java)

В вашем файле gradle добавьте строку ниже (отметьте здесь для последнего номера версии в readme)   compile 'com.firebaseui: firebase-ui-database: 0.4.3'