【问题标题】:Knowing when Firebase has completed API call?知道 Firebase 何时完成 API 调用?
【发布时间】:2016-07-20 08:16:25
【问题描述】:

我无法知道我的 Firebase API 调用何时完成。看完Firebase documentation我发现如下:

值事件总是最后触发,并保证包含在拍摄快照之前发生的任何其他事件的更新。

我理解这意味着只有在所有 onChildAdded 调用完成后,才会调用 ValueEventListener。结果,我认为我可以在onChildAdded 函数中填充我的RecyclerView,然后在onSingleValueListener 调用中填充,我可以简单地完成加载屏幕的动画(在此函数调用之前已经开始动画)并继续。但是,我遇到了一个问题,我仔细地添加了System.out.println 语句,发现在我的情况下,Test 1 在调用Test 2 之前被调用。这会导致问题,因为这实际上与我想要的行为相反:我希望 onChildAdded 函数完成,然后调用打印出 Test 1onSingleValueListener 函数以被调用。发生这种情况有什么原因吗?有什么办法吗?我希望能解释为什么会发生这种情况。谢谢!

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) {

        }
    });
} 

【问题讨论】:

  • "Firebase linkRef = firebaseRef.child("/posts/" + postId);"我认为您使用的是旧版 Firebase API;我说的对吗?
  • 参考此文档并在新的 Firebase 数据库 API 中试用; "firebase.google.com/docs/database/android/start";

标签: android asynchronous firebase firebase-realtime-database


【解决方案1】:

您可能想要使用 Firebase 团队在 FirebaseUI-Android 中提供的 **FirebaseRecyclerAdapter** 类(请参阅 https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java

在您的 gradle 文件中添加以下行(检查 here 以获取自述文件中的最新版本号) 编译'com.firebaseui:firebase-ui-database:0.4.3'

【讨论】:

  • 为这个 Erstwhilell 干杯,我什至不知道 Firebase 提供了回收器适配器!
【解决方案2】:

使用此代码"Firebase linkRef = firebaseRef.child("/posts/" + postId);" 我可以看到您使用的是旧版 Firebase API。 现在已弃用!

请将您的代码更新为新的 Firebase 3.x.x API。

下面两个是独立的异步调用;根据您的用例,您可以使用任一侦听器来读取您的数据。

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

您可以参考 firebase 文档以获取有关数据库侦听器的更多信息。 https://firebase.google.com/docs/database/android/retrieve-data

使用以下代码 sn-p,您可以检索并填充您的 cmets 列表。

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
        }
    });

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 2021-01-19
    相关资源
    最近更新 更多