查询来自Firebase的数据 [英] Querying data from firebase

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

问题描述

我试图从我的firebase数据库中获取项目列表...但是我有一个获取它们的问题。
我的代码看起来或多或少是这样的:

  List< Items> itemsList; 

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

itemsList = GetItems();
}

以及应该返回我的项目的方法如下所示:

  private ArrayList< Items> GetItems(){
DatabaseReference数据库= 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 $ b $ public void onDataChange(DataSnapshot dataSnapshot){$ b $ if(dataSnapshot.exists()){
for(DataSnapshot singleSnapshot:dataSnapshot.getChildren()){
Items item = singleSnapshot.getValue(Items.class);
itemsRez.add(item);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError){
$ b}
});
返回itemsRez;



$ b

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

addListenerForSingleValueEvent()时,Firebase客户端开始加载服务器中的数据,可能需要一些时间。为防止阻塞您的应用程序(这将导致应用程序不响应对话框),它会将数据加载到单独的线程中。所以当数据加载的时候,你的主线程继续并返回当前状态 itemsRez ,这是一个空列表。


$ b $如果在代码中添加一些日志语句,最简单的方法就是看这个:

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

System.out.println(附加侦听器);
itemsQuery.addListenerForSingleValueEvent(new ValueEventListener(){
@Override $ b $ public void onDataChange(DataSnapshot dataSnapshot){$ b $ 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);
返回itemsRez;





$ b与您期望的相反,这将按以下顺序打印日志记录:


附加监听器

返回0个项目

收到的项目

解决您的问题的一个常见方法是重新构建您的代码目标。不要写先拿到项目,然后再去做,把代码写成开始获取项目,然后当他们进来时,对他们进行abc。在代码中,这意味着将需要 itemsRec 的代码移动到 onDataChange 方法中,其中它会被调用在正确的时刻:当项目已经加载。

另见:


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

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?

解决方案

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:

Attaching listener

Returning 0 items

Received items

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.

Also see:

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

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