从 Firebase 查询数据 [英] Querying data from firebase

查看:23
本文介绍了从 Firebase 查询数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从我的 firebase 数据库中获取项目列表……但是我在获取它们时遇到了问题.我的代码看起来或多或少是这样的:

I am trying to get a list of items from my firebase database...but I have a problem obtaining them. My code looks more or less like this:

List<Items> itemsList;

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

    itemsList = GetItems();
}

应该返回我的项目的方法如下:

and the method that should return my items looks like:

private ArrayList<Items> GetItems(){
    DatabaseReference database = FirebaseDatabase.getInstance().getReference();
    DatabaseReference ref = database.child("items");
    final ArrayList<Items> itemsRez = new ArrayList<Items>();
    Query itemsQuery = ref.orderByChild("type");

    itemsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
                    Items item = singleSnapshot.getValue(Items.class);
                    itemsRez.add(item);
                }
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return itemsRez;
}

GetItems() 总是返回一个空列表,这有点道理,因为在我返回这个列表之前没有什么可以触发 onDataChange 事件,所以我的问题是......我怎样才能让这个方法返回来自 DB 的项目列表?

The GetItems() always returns me a null list, which kinda makes sense, as there is nothing to fire the onDataChange event before I return this list, so my question is...how can I make this method to return the list of items from DB?

推荐答案

当您调用 addListenerForSingleValueEvent() 时,Firebase 客户端开始从服务器加载数据,这可能花一些时间.为了防止阻塞您的应用程序(这会导致应用程序无响应对话框),它会在单独的线程中加载数据.因此,在加载数据时,您的主线程继续运行并返回 itemsRez 的当前状态,这是一个空列表.

When you call addListenerForSingleValueEvent() the Firebase client starts loading the data from the server, which may take some time. To prevent blocking your app (which would lead to an Application Not Responding dialog), it loads the data in a separate thread. So while the data is loading, your main thread goes on and returns the current state of itemsRez, which is an empty list.

如果您在代码中添加一些日志记录语句,最容易看到这一点:

It's easiest to see this if you add a few logging statements to your code:

private ArrayList<Items> GetItems(){
    DatabaseReference database = FirebaseDatabase.getInstance().getReference();
    DatabaseReference ref = database.child("items");
    final ArrayList<Items> itemsRez = new ArrayList<Items>();
    Query itemsQuery = ref.orderByChild("type");

    System.out.println("Attaching listener");
    itemsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
                    Items item = singleSnapshot.getValue(Items.class);
                    itemsRez.add(item);
                }
            }
            System.out.println("Received "+itemsRez.size()+" items");
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    System.out.println("Returning "+itemsRez.size()+" items");
    return itemsRez;
}

与您可能期望的相反,这将按以下顺序打印日志:

Contrary to what you likely expect, this will print the logging in this order:

附加监听器

返回 0 个项目

收到的物品

解决您的问题的一种常见方法是重新构建代码的目标.不要写先拿到物品,然后用它们做 abc",把代码写成开始拿到物品.然后当它们进来时,用它们做 abc".在代码中,这意味着您将需要 itemsRec 的代码移动到 onDataChange 方法中,该方法将在适当的时刻被调用:当项目已加载.

One common solution to your problem is to reframe the goal of you code. Instead of writing "first get the items, then do abc with them", write the code as "start getting the items. Then when they come in, do abc with them". In code that means you move the code that needs itemsRec into the onDataChange method, where it will be invoked at the right moment: when the items have loaded.

另见:

这篇关于从 Firebase 查询数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆