Skip to content
Advertisement

Arraylist error index out of bound or it is null

As we know there is no multi query option to firebase realtime database, so instead of using default FirebaseRecycler methods I am trying to manually feed keys from arraylist to the recycler view. In order to sort specific keys on the basis specific child nodes of the given parent I wrote below logic.

If I try to individually log the keys in if statement it shows displays all the sorted keys.

But now my problem is whenever I try to log the arraylist after fetching the values it shows null and if I log specific value at some index below error shows up.

public class categorizedProducts extends AppCompatActivity {

    private String catKey;
    private DatabaseReference productRef, catRef;
    private ArrayList<String> keyVal = new ArrayList<>();
    private long count = 0;
    private long i = 0;

   
    private void queryLogic(final String catTitle) {

        productRef.orderByChild("count").addValueEventListener(new ValueEventListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                count = dataSnapshot.getChildrenCount();

                for (final DataSnapshot snap: dataSnapshot.getChildren()){

                    productRef.child(Objects.requireNonNull(snap.getKey())).addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                            if (Objects.requireNonNull(dataSnapshot.child("category").getValue()).toString().equals(catTitle)) {

                                //keyVals.add(snap.getKey());
                                keyVal.add(snap.getKey());
                                i++;

                            }

                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });

                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }
    // I am trying to log my arraylist here after retrieving the required keys from database

}


2020-06-27 19:50:32.315 567-567/com.kalpana.mortoys E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.kalpana.mortoys, PID: 567
    java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.kalpana.mortoys.categorizedProducts$1.onDataChange(categorizedProducts.java:65)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.2.1:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.2.1:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.2.1:55)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7397)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

I temporarily solved my error using this

public class categorizedProducts extends AppCompatActivity {

    private String catKey;
    private DatabaseReference productRef, catRef;
    private ArrayList<String> keyVal = new ArrayList<>();

    private long count = 0, i = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_categorized_products);

        initFields();

        try {
            Bundle bundle = getIntent().getExtras();
            assert bundle != null;
            catKey = bundle.getString("key");

            assert catKey != null;
            catRef.child(catKey).addValueEventListener(new ValueEventListener() {
                @RequiresApi(api = Build.VERSION_CODES.KITKAT)
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {


                    queryLogic(Objects.requireNonNull(dataSnapshot.child("catTitle").getValue()).toString());

                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });


        }
        catch (NullPointerException e) {

            e.printStackTrace();

        }

    }

    private void initFields() {

        productRef = FirebaseDatabase.getInstance().getReference().child("products");
        catRef = FirebaseDatabase.getInstance().getReference().child("categories");

    }

    @Override
    protected void onStart() {
        super.onStart();


        if (i == count) {

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {

                    Log.i("TAG", "onStart: " + keyVal);

                }
            }, 3000);


        }

    }

    private void queryLogic(final String catTitle) {

        productRef.orderByChild("count").addValueEventListener(new ValueEventListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                count = dataSnapshot.getChildrenCount();

                for (final DataSnapshot snap: dataSnapshot.getChildren()){


                    i++;

                    productRef.child(Objects.requireNonNull(snap.getKey())).addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                            if (Objects.requireNonNull(dataSnapshot.child("category").getValue()).toString().equals(catTitle)) {

                                //keyVals.add(snap.getKey());
                                keyVal.add(snap.getKey());

                                //Log.i("TAG", "onDataChange: " + i);

                            }

                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });

                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }

}

but still need an perfect solution

Advertisement

Answer

You could use a callback interface:

interface CallBack {public void done()}

and call queryLogic() as

queryLogic(catTitle,new CallBack() {
    public void done() {
        //log your arrayList here
    }
});

private void queryLogic (final String catTitle,final CallBack callBack){..}

and after the iteration is over just call the method callBack.done().

6 People found this is helpful
Advertisement