0

I am a beginner so apologies for a possible silly question.

I am trying to retrieve data from a Firebase database. This works but I cannot assign the value to a string variable for use later on.

This is the asynchronous call to the database which returns the right result. (The data its querying from is static so I don't really need an asynchronous call but as far as I am aware, I don't have another option).

 public static void getAnimalDetails(String strColl, final String strQueryField, final String strQueryValue,
                                         final MyCallBack myCallback){

        mfirebaseDb.collection(strColl)
                .whereEqualTo(strQueryField, strQueryValue)
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {

                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful()) {

                            for (QueryDocumentSnapshot document : task.getResult()) {

                                    String strResult = document.get("animal_class").toString();
                                    Log.d(TAG, "SSSS:" + strResult );
                                    myCallback.onCallback(strResult);

                            }



                        }
                    }
                });

    }

This is the callback function passed to the method above.

    public interface MyCallBack {
        void onCallback(String strValFromAsyncTask);
    }

Then this is where I call the asynch task and try and access the data from the callback. This method fires on a button click I can see via the log that the right value is populated in strAnimalClass (which is a global variable) But when I try to use strAnimalClass outside of the call back it is null.

        getAnimalDetails("animals", "animal_common_name", animal, new MyCallBack() {
            @Override
            public void onCallback(String strValFromAsyncTask) {

                strAnimalClass = strValFromAsyncTask;
                Log.d(TAG, "mmmmm:" + strAnimalClass );
            }
        });

Can anyone help with how to get a value like this out of the async / callback environment for use later on? Thank you

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Jon
  • 55
  • 2
  • 15

1 Answers1

0

You can't use the value outside of the callback. Or more specifically, you can use the value outside of the callback, but not before the callback has been called. This same rule applies to Firebase's onComplete and to your custom onCallback method.

You can verify that with a few log lines:

Log.d(TAG, "Before calling getAnimalDetails")
getAnimalDetails("animals", "animal_common_name", animal, new MyCallBack() {
    @Override
    public void onCallback(String strValFromAsyncTask) {
        Log.d(TAG, "Inside onCallback");
    }
});
Log.d(TAG, "After calling getAnimalDetails")

When you run this code, it logs:

Before calling getAnimalDetails

After calling getAnimalDetails

Inside getAnimalDetails

So while you can access strAnimalClass after the code that calls getAnimalDetails, it won't have the expected value yet, because onCallback wasn't called yet.

For this reason any code that needs the value(s) from the database will need to be inside onComplete or inside onCallback, or be called from within there.

Also see:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you so much, I suspected as much. I will try and run all the required code from within the callback or within the initial onCompleteListener – Jon Nov 29 '19 at 05:57