Data from Firebase takes a long time to complete loading and hinders sorting objects

Asked

Viewed 118 times

3

I’m trying to sort an object by a value that comes from Firebase. I use a Jsonparcer class to list the database and according to the ID take the field I need in Firebase, which in this case is a coordinate so that with it I calculate the distance. The ordination will be done by this field.

1. I call Jsonparcer at the Ansyctask doInBackground.

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

3. Then I add in Adapter to Recyclerview.

PROBLEM: Some objects do not finish being loaded in the Firebase Query and when they arrive in Onpostexecute they have nulls or Zero values, disturbing the ordering.

PRECISE: Order only when all objects are filled with Firebase values, so that soon after I play in my Adapter.

I’ll throw the classes below and an example of how the dice come:

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 below the interaction of the data and check that some data from Firebase arrive only later, which hinders the perfect ordering that I run inside the 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

1 answer

0

Big problem this huh, since Firebase is async (too), I could only think about putting the firebase query inside a while, and wait for everything to end there, and this all within a thread, not to disturb the UI, but it seems to me that your class MototaxiJSONParcer is already called at 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;
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.