0

I am currently trying to get tokens from a Realtime Database (Firebase) using Retrofit2 and Gson, in Android Studio. My API class and TokensService is correctly defined, and I'm using the .enqueue() method in order to perform the GET command.

TokensService

public interface TokensService {

    @GET("Tokens.json")
    Call<Object> getAllTokens();

    @POST("Tokens.json")
    Call<Object> postToken(@Body Tokens miToken);

}

HelperTokens

public ArrayList<Tokens> getTokens() {
        Arraylist<Tokens> listTokens=new ArrayList<>();
        Retrofit myRetro = APIService.getInstancia();
        TokensService myTokensService = myRetro.create(TokensService.class);

            myTokensService.getAllTokens().enqueue(new Callback<Object>() {
                @Override
                public void onResponse(Call<Object> call, Response<Object> response) {

                    //Here, I verified that the info is being received in the response.body()

                    Map<String,Map> datos = (Map<String, Map>) response.body();

                    for (Map.Entry<String, Map> item : datos.entrySet()){
                        Log.d("Entered the for loop","iterations");
                        Tokens eachToken = new Tokens();
                        eachToken.setTheToken((String) item.getValue().get("theToken"));
                        eachToken.setfCreacion((String) item.getValue().get("fCreacion"));
                        eachToken.setLimited((double) item.getValue().get("isLimited"));
                        eachToken.setfVencimiento((String) item.getValue().get("fVencimiento"));

                        //Here, I assign each attribute to a new instance of "Tokens" and add it
                        //to the Arraylist that will be returned from getTokens()

                        listTokens.add(eachToken);
                    }
                    Log.d("Finishing onResponse, this is the Arraylist",listTokens.toString());
                }
                @Override
                public void onFailure(Call<Object> call, Throwable t) {
                    Log.d("Fallo",t.getMessage());

                }
            });

        Log.d("Arraylist about to be returned",listTokens.toString());

        return listTokens;

    }

However, I'm having trouble with getting this right. There is no error, but the execution order looks a bit weird. As soon as I call the method getTokens() on my java.class, it goes through each line, creates the Arraylist, gets the Retrofit instance (singleton), creates the TokensService class, and finally arrives at the getAllTokens().enqueue().

But it returns listTokens before entering the onResponse/onFailure. It returns an empty array, and just then goes into the onResponse and performs all it's tasks switfly. But there's nothing I can do with the empty Arraylist it returns. Is almost like onResponse executes with a delay

Check the Logs and compare them to the following Logcat, so you can get what I'm talking about.

ANNOTATIONS:

The class for a singular instance is called Tokens, in plural. "Token" would be hard to work with, since is a word used in a lot of methods and commands, and etc. So keep it in mind.

I just have one single Tokens up in the Realtime Database, so in the "filled" listTokens, you can only observe 1 Tokens being added. It's not because the for is only iterating once. I've tested it, and iterates as many times as there are Tokens in the database.

Since I first thought it may be a online-type issue, like a little delay in the connection, I tried to Thread.sleep() the program, so that the connection would have time more than enough to perform it's duties. But no matter how much time it sleeps, the return command keeps executing before the onResponse

DFDev3
  • 1
  • 1
  • From the structure of your code it looks like `enqueue` queues a callback object, which will then be executed asynchronously. In other words, your code continues onward in your thread while the callback is run on another thread. If you expect the return to wait for completion of the request you will need to synchronize. That will depend on the implementation of `TokensService`. – Jim Garrison May 23 '23 at 00:42
  • I just updated the question with TokensService interface. How should I modify it in order to make execute() a suitable option for the request? – DFDev3 May 23 '23 at 02:08
  • There is no way you can return the `listTokens` as a result of a method, even if you're using Retrofit. Firebase API is asynchronous. So please check the duplicate to see how can you solve this using a callback. You might also be interested in reading this [resource](https://medium.com/firebase-tips-tricks/how-to-read-data-from-firebase-realtime-database-using-get-269ef3e179c5). – Alex Mamo May 23 '23 at 05:54

0 Answers0