0

I stored datas from the database to an arrayList called nameList.

Within the function 'get_spinner_info', the values are successfully stored within the nameList.

However, there is no value for nameList outside of this function.

The error code is " java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 ".

I really need your help.


public class my_Item {
    private Context context;
    private FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference datebaseReference = firebaseDatabase.getReference();
    ArrayList<String> nameList = new ArrayList<String>();

    
    // Get the value from the database and put them in the 'nameList'.
    //In this code, I can successfully check the value within the 'nameList'.
    public void get_spinner_info(String brand, String item, String prod_key){
        datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot ds : dataSnapshot.child("myValue").getChildren()) {
                    String prod_name = ds.getValue().toString();  
                    nameList.add(prod_name);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }


    // But the nameList is empty in this part.
    public void callFunction(final String brand, final String item, final String product_name, final String product_key, final int product_Num) {
        get_spinner_info(brand, item, product_key);
        Log.d("Spinner namelist :  ", nameList.get(0));
    }
}
2
  • Does that piece of code compile on your machine? I don't see a class definition. Commented Nov 9, 2020 at 14:39
  • Yes, I only brought the code for the part with the error. Commented Nov 9, 2020 at 14:41

2 Answers 2

1

get_spinner_info method starts and ASYNCHRONOUS data loading (registers lsitener), thus onDataChange will get called after Log.d("Spinner nameList : ", nameList.get(0));

your data will be available only after onDataChange call, which may take some time. get_spinner_info just starts loading your data, doesn't means that all data will be available just after method call ends

put this on the end of onDataChange (after current for loop) to check your items available/present in array

for (String name : nameList) Log.d("Spinner", "name: " + name);
Sign up to request clarification or add additional context in comments.

3 Comments

I applied this method, but the result is same. The output is successful, but the nameList still cannot be accessed only within 'callFunction'... But thank you for your answer
yes, it won't be present there, because all its code run immediately (currently two methods get_spinner_info and Log.d one after another) and datebaseReference takes some time, fetch data ASYNCHRONOUSLY and returns it in onDataChange - this is the first moment in which you can access data. stright inside callFunction data won't be present, thats how asynchronous data fetching works...
just put some Log.d on the end of onDataChange and you will see that data arrives few milisecs after Log.d("Spinner namelist : ", nameList.get(0)); (replace nameList.get(0) to nameList.size() to avoid exception accessing 0-index item in empty array at this moment
0

Synchronization problem cause this kind of error

if you already have data do this

create interface class

public interface DataCallback {
    public void reciveData(ArrayList<String> nameList ,boolean isOk);
}

In your class my_Item call the interface like this

    public void get_spinner_info(String brand,String item,String prod_key,DataCallback callback){
            datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener(){
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot){
            for(DataSnapshot ds:dataSnapshot.child("myValue").getChildren()){
            String prod_name=ds.getValue().toString();
            nameList.add(prod_name);
            }
            // here you should check if the result available or NOT to prevent null exceptions 
            if(nameList.size()>0){
            callback.reciveData(nameList,true);// true and false used to check data if available or null
            }
            else{
            callback.reciveData(nameList,false);
                            
                            }
            }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError){

               }
                });
   }

Now when you call get_spinner_info you need the callback Like this

get_spinner_info(brand, item, product_key,new DataCallback() {
    @Override
    public void callback(ArrayList<String> nameList, boolean isOk) {
        if (isOk){
            /// you have all data recived
            Log.d("Spinner namelist :  ", nameList.get(0));
        }else {

            // no data available
            Log.i("TAG", "callback: No Data Available");
        }
    }
}););

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.