Firebase/Android:将从 Firebase 检索到的值添加到 arraylist 返回空指针异常 [英] Firebase/Android: Adding retrieved values from Firebase to arraylist returns null pointer exception

查看:15
本文介绍了Firebase/Android:将从 Firebase 检索到的值添加到 arraylist 返回空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 Firebase 数据库中检索到的值添加到 Arraylist,然后再从那里添加到 String 数组.我的检索方法工作正常.我可以在祝酒词中打印出所有值.但显然它没有被添加到数组列表中.

I'm trying the add the retrieved values from Firebase database to an Arraylist and from there to a String array. My retrieval method works fine. I can have all the values printed out in a toast. But apparently it doesn't get added to the arraylist.

这是我在片段类的 onActivityCreated() 中检索的代码.

Here's my code for retrieval in onActivityCreated() of fragment class.

ArrayList<String> allBrands = new ArrayList<>();
brandRef=FirebaseDatabase.getInstance().getReferenceFromUrl("https://stockmanager-142503.firebaseio.com/Brands");
        q=brandRef.orderByChild("brandName");
        q.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
               allBrands.add((dataSnapshot.getValue(Brand.class)).getBrandName());
                Toast.makeText(getActivity(),(dataSnapshot.getValue(Brand.class)).getBrandName(), Toast.LENGTH_SHORT).show();

            }

            @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(DatabaseError databaseError) {

            }
        });

这就是我尝试在 Fragment 类的 OnActivityResult() 方法中使用 arrayList 的地方,但我相信没有执行迭代器循环.没有看到吐司.当我尝试使用数组时,出现空指针异常.我假设这些值不会被复制到品牌数组中.

And this is where I'm trying to use the arrayList in OnActivityResult() method of the Fragment class but the iterator loop is not executed I believe. The toast is not seen. I'm getting a null pointer exception when I try to work with the array. I assume the values do not get copied to the brands array.

count=allBrands.size();
                                String[] brands=new String[count];
                                Iterator<String> itemIterator = allBrands.iterator();
                                if(itemIterator.hasNext()){
                                    //brands[i] = itemIterator.next();
                                    Toast.makeText(getActivity(), itemIterator.next(), Toast.LENGTH_SHORT).show();
                                   // i++;

                                }
                               for( i=0;i<count;i++){
                                    if(brands[i].compareTo(Brand)==0){
                                        f=1;break;
                                    }
                                }

这是我的数据库,以防万一.但是我可以毫无问题地打印出 Toast 中所有检索到的值.

Here's my database in case that helps. But I can print out all the retrieved values in a Toast with no problem.

推荐答案

从您共享的代码中很难确定,因为我怀疑您可能会被 Firebase 异步加载所有数据这一事实所困扰.或者,您可能根本没有读取数据的权限.两个我都会回答.

It's hard to be certain from the code you shared, by I suspect you may be bitten by the fact that all data is loaded from Firebase asynchronously. Alternatively you may simply not have permission to read the data. I'll give an answer for both.

将一些日志语句添加到代码的最小片段中时,最容易理解这种行为:

It's easiest to understand this behavior when you add a few log statements to a minimal snippet of your code:

System.out.println("Before attaching listener");
q.addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        System.out.println("In onChildAdded");    
    }
    public void onChildChanged(DataSnapshot dataSnapshot, String s) { }
    public void onChildRemoved(DataSnapshot dataSnapshot) { }
    public void onChildMoved(DataSnapshot dataSnapshot, String s) { }
    public void onCancelled(DatabaseError databaseError) { }
});
System.out.println("After attaching listener");

此代码段的输出将是:

附加监听器之前

附加监听器后

在 onChildAdded 中(可能多次)

In onChildAdded (likely multiple times)

这可能不是您期望的输出顺序.这是因为 Firebase(与大多数云 API 一样)异步加载数据库中的数据:它不会等待数据返回,而是继续运行主线程,然后在数据可用时回调到您的 ChildEventListener.onChildAdded.

This is probably not the order you expected the output in. This is because Firebase (like most cloud APIs) loads the data from the database asynchronously: instead of waiting for the data to return, it continues to run the code in the main thread and then calls back into your ChildEventListener.onChildAdded when the data is available.

Android 上没有办法等待数据.如果您这样做,您的用户会感到害怕应用程序无响应".对话框,您的应用将被终止.

There is no way to wait for the data on Android. If you'd do so, your users would get the daunted "Application Not Responding" dialog and your app would be killed.

因此,处理此 API 的异步性质的唯一方法是将需要具有新数据的代码放入 onChildAdded() 回调中(也可能放入其他回调中)某点):

So the only way to deal with the asynchronous nature of this API is to put the code that needs to have the new data into the onChildAdded() callback (and likely into the other callbacks too at some point):

q.addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        allBrands.add((dataSnapshot.getValue(Brand.class)).getBrandName());  
        System.out.println(allBrands.length); 
    }

您需要获得读取数据的权限

您需要获得从某个位置读取数据的权限.如果您没有权限,Firebase 将立即取消侦听器.你需要在你的代码中处理这个条件,否则你永远不会知道.

You need permission to read the data

You need permission to read the data from a location. If you don't have permission, Firebase will immediately cancel the listener. You need to handle this condition in your code, otherwise you'll never know.

public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException();
}

这篇关于Firebase/Android:将从 Firebase 检索到的值添加到 arraylist 返回空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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