java – Data coming from Firebase takes a long time to finish loading and interferes with the ordering of objects

Question:

I'm trying to order an object by a value that comes from Firebase. I use a JsonParcer class to list the database and according to the ID I get the field I need in Firebase, which in this case is a coordinate so that I can calculate the distance with it. Sorting will be done by this field.

1. I call JsonParcer in AnsycTask's doInBackground.

2. In onPostExecute I call the Collection.Sort(data).

3. Then I add in Adapter for RecyclerView.

PROBLEM: Some objects do not finish being loaded in the Firebase Query and when they arrive at OnPostExecute they have nulls or zero values, interfering with the ordering.

I NEED: That the ordering is only done when all the objects are filled with Firebase values, so that soon after I play it on my adapter.

I'll throw the classes below and an example of how the data comes:

public class MototaxiJSONParcer {

    static LatLng currentLocationLatLong;

    public static List<TaxiMototaxiEtc> parseDados(String content, final LatLng coordenadaUsu) {


        try {
            JSONArray jsonArray = new JSONArray(content);
            final List<TaxiMototaxiEtc> dadosList = new ArrayList<>();

            for (int i = 0; i< jsonArray.length(); i++) {

                final JSONObject jsonObject = jsonArray.getJSONObject(i);
                final TaxiMototaxiEtc dados = new TaxiMototaxiEtc();


                // Pegar ID, ir no DateTime e buscar Coordenada ------------------------------------
                DatabaseReference raiz = FirebaseDatabase.getInstance().getReference();
                Query consultaRealTime;
                consultaRealTime = raiz.child("location/" + jsonObject.getString("id")).limitToLast(1);
                final int finalI = i;
                consultaRealTime.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        LocationData localizacao = new LocationData();
                        for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
                            localizacao = childSnapshot.getValue(LocationData.class);
                        }

                        currentLocationLatLong = new LatLng(localizacao.latitude, localizacao.longitude);

                        if (currentLocationLatLong != null) {
                            int distancia = (int) SphericalUtil.computeDistanceBetween(currentLocationLatLong, coordenadaUsu);

                            dados.setDistancia(distancia);

                        }

                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        Log.i("Local", "The read failed: " + databaseError.getCode());
                    }
                });

                dados.setName(jsonObject.getString("name"));
                dadosList.add(dados);


            } // end For


            return dadosList;

        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

}

INTERACTION: Check the data interaction below and check that some Firebase data only arrives later, which hinders the perfect ordering I perform inside DoInBackGround:

DENTRO DO PARCER: Teones - 3491
DENTRO DO PARCER: Gabriel - 2663
DENTRO DO PARCER: Alisson - 3564
----------------------------------------------------------------
SEM ORDENAR: Teones - 3491
SEM ORDENAR: Gabriel - 2663
SEM ORDENAR: Alisson - 3564
SEM ORDENAR: Carlos Augusto - 0
SEM ORDENAR: Tiago Fontes - 0
SEM ORDENAR: Jaciene - 0
-----------------------------------------------------------------
ORDENADO: Carlos Augusto - 0
ORDENADO: Tiago Fontes - 0
ORDENADO: Jaciene - 0
ORDENADO: Gabriel - 2663
ORDENADO: Teones - 3491
ORDENADO: Alisson - 3564

DENTRO DO PARCER: Carlos Augusto - 1918
DENTRO DO PARCER: Tiago Fontes - 4042
DENTRO DO PARCER: Jaciene - 4337802

Answer:

That's a problem, since Firebase is async (also), I just managed to put the firebase query inside a while, and wait for everything to finish there, and that's all inside a thread, so as not to disturb the UI, but it seems to me that your MototaxiJSONParcer class is already called in doInBackground, so you can try it like this:

AtomicBoolean consultaCompleta = new AtomicBoolean(false);
consultaRealTime.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        LocationData localizacao = new LocationData();
        for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
            localizacao = childSnapshot.getValue(LocationData.class);
        }

        currentLocationLatLong = new LatLng(localizacao.latitude, localizacao.longitude);

        if (currentLocationLatLong != null) {
            int distancia = (int) SphericalUtil.computeDistanceBetween(currentLocationLatLong, coordenadaUsu);
            dados.setDistancia(distancia);
        }
        dados.setName(jsonObject.getString("name"));

        consultaCompleta.set(true);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        consultaCompleta.set(true);
        Log.i("Local", "The read failed: " + databaseError.getCode());
    }
});

while (true) {
    // TODO: isso pode demorar a vida toda, considere adicionar um timeout
    if (consultaCompleta.get()) {
        dadosList.add(dados);
        break;
    }
}
Scroll to Top