Android:Firebase 花费太多时间来获取数据

Posted

技术标签:

【中文标题】Android:Firebase 花费太多时间来获取数据【英文标题】:Android: Firebase taking too much time to fetch data 【发布时间】:2016-10-08 17:48:22 【问题描述】:

我在我的应用程序中使用 Firebase 的实时数据库功能。数据库如下所示:

节点 104、1040...具有更多元素/数据。我正在获取此数据,在每个 Integer 父级中可用的节点“updatedAt”上按值对其进行排序,如快照所示。我正在使用 onChildAddedListener() 来获取最后 20 个元素。 “结果”中有大约 1050 个节点。

问题:

    即使在高速 WiFi 上,获取数据也需要花费太多时间,大约 30 秒。

    Firebase 是否允许任何回调来通知已获取数据?我想将每个自定义对象附加到从 Firebase 收到的 ArrayList 并通过意图将其传递给另一个活动。我正在计算收到的对象,当它变成 20 时,我打开了我的活动。这是唯一的方法吗?如果有更好的出路,请提出建议。

这是我的代码:

 public class Splash extends AppCompatActivity

        private static final String TAG = "Splash Activity";
        private ArrayList<News> NewsArrayList = new ArrayList<>();   
        private DatabaseReference newsReference;
        private int position = 0;

        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_splash);

            newsReference = FirebaseDatabase.getInstance().getReference().child("results");
            Query queryNewsReference = newsReference.orderByChild("updatedAt").limitToLast(20);
            fetchNews(queryNewsReference);
        

        private void fetchNews(Query queryNewsReference) 

            queryNewsReference.addChildEventListener(new ChildEventListener() 
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) 
                    Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
                    News newsObject = dataSnapshot.getValue(News.class);
                    Log.d(TAG,"News Title: "+ newsObject.getVideo_title());
                    NewsArrayList.add(newsObject);
                    position++;
                    if(position == 20)
                    startMainActivity(); 
                    
                
                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s)
                    Log.d(TAG, "onChildChanged() called on key: "+ dataSnapshot.getKey());
                

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) 
                    Log.d(TAG, "onChildRemoved() called on key: "+ dataSnapshot.getKey());
                

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) 
                    Log.d(TAG, "onChildMoved() called on key: "+ dataSnapshot.getKey());
                

                @Override
                public void onCancelled(DatabaseError databaseError) 
                    Log.e(TAG,"Database Error: "+databaseError.toString());
                
            );
        

        private void startMainActivity() 
            Intent intent = new Intent(Splash.this,MainActivity.class);
            intent.putExtra("NewsList",NewsArrayList);
            Splash.this.startActivity(intent);
        

【问题讨论】:

在您看到第一条“onChildAdded”logcat 消息之前是否会出现 30 秒延迟?一旦你看到第一个“onChildAdded”,其他的会立即跟进吗? @qbix 是的。在我看到第一个“onChildAdded”之前有 30 秒的延迟。 BTW 有什么区别?如果 onChildAdded() 被调用,那么这意味着数据已经被获取,对吧? 只是在寻找线索。 FWIW 我创建了一个与您的非常相似的测试用例(1100 个对象,按孩子排序,仅限于最后 20 个)并且没有看到延迟。我在加利福尼亚——与服务器的连接可能比你更好。 @qbix:我明白了。除此之外,关于我在问题中的第二点。这是正确的做法吗?或者如果有更好的方法,请提出建议。 @Frank van Puffelen 作为 Firebase 的一名工程师,如果您能提供您的见解,那就太好了。谢谢! 【参考方案1】:

在添加值监听器之前尝试重新连接到 Firebase:

private void fetchNews(Query queryNewsReference) 
    
    if (FirebaseDatabase.getInstance() != null)
    
        FirebaseDatabase.getInstance().goOffline();
    

    FirebaseDatabase.getInstance().goOnline();

    queryNewsReference.addChildEventListener(new ChildEventListener() 

    ...

【讨论】:

以上是关于Android:Firebase 花费太多时间来获取数据的主要内容,如果未能解决你的问题,请参考以下文章

从服务器检索数据花费了太多时间

嵌套的 Foreach 循环花费了太多时间

是否可以像在 Android Studio 中一样在 Eclipse 中使用 Firebase? [复制]

Redshift 查询花费太多时间

Oracle 通过存储过程进行批量插入。花费太多时间

UIScrollView 花费太多时间