java android firebase google-cloud-firestore

java - Espere hasta que se recuperen los datos de Firestore para iniciar una actividad



android firebase (1)

No puedes usar algo ahora que no ha sido cargado todavía. Firestore carga datos de asynchronously , ya que puede llevar algo de tiempo. Dependiendo de la velocidad de su conexión y del estado, pueden pasar de unos pocos cientos de milisegundos a unos pocos segundos antes de que los datos estén disponibles. Si desea pasar una lista de objetos de tipo Attraction a otro método, simplemente llame ese método dentro del método onSuccess() y pase esa lista como un argumento. Así que una solución rápida sería esta:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); CollectionReference attractionsRef = rootRef.collection("attractions"); attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { List<Attraction> attractionsList = new ArrayList<>(); for (QueryDocumentSnapshot document : task.getResult()) { Attraction attraction = document.toObject(Attraction.class); attractionsList.add(attraction); } methodToProcessTheList(attractionsList); } } });

Así que recuerde, el método onSuccess() tiene un comportamiento asíncrono, lo que significa que se llama incluso antes de que obtenga los datos de su base de datos. Si desea utilizar la lista de attractionsList fuera de ese método, debe crear su propia callback . Para lograr esto, primero necesitas crear una interfaz como esta:

public interface MyCallback { void onCallback(List<Attraction> attractionsList); }

Luego, debe crear un método que realmente obtenga los datos de la base de datos. Este método debería verse así:

public void readData(MyCallback myCallback) { attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { List<Attraction> attractionsList = new ArrayList<>(); for (QueryDocumentSnapshot document : task.getResult()) { Attraction attraction = snapshot.toObject(Attraction.class); attractionsList.add(attraction); } myCallback.onCallback(attractionsList); } } }); }

Al final, simplemente llame readData() método readData() y pase una instancia de la interfaz MyCallback como un argumento donde lo necesite de esta manera:

readData(new MyCallback() { @Override public void onCallback(List<Attraction> attractionsList) { //Do what you need to do with your list } });

Esta es la única forma en que puede usar ese objeto attractionsList fuera del método onSuccess() . Para más información, también puede echar un vistazo a este video .

Hice una lista de objetos POJO que obtienen valores de mi base de datos de Cloud Firestore. Esta lista es en sí misma una clase que tiene en mente recuperar atributos cada vez que creo una nueva lista. La cosa es que la Lista no se rellena en la actividad de creación sino en el tiempo posterior. He intentado agregar bucles, tareas, esperas, pero no obtener el resultado deseado. Aquí es cómo recupero mis datos satisfactoriamente:

private void retrieveData(){ reference = firestore.collection("attractions"); reference.addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) { attractionList.clear(); for (DocumentSnapshot snapshot : queryDocumentSnapshots) { Attraction attraction = snapshot.toObject(Attraction.class); addAttractions(attraction); } } }); }

Recupero los datos cada vez que creo un nuevo Objeto:

public AttractionList() { firestore.setFirestoreSettings(settings); reference = firestore.collection("attractions"); attractionList = new ArrayList<>(); retrieveData(); }

Luego, si reviso el tamaño de la Lista en mi Actividad en crear:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_attraction); Toolbar toolbar = findViewById(R.id.tb_attraction); setSupportActionBar(toolbar); //Creating POJO List and retrieving data attractionList = new AttractionList(); Log.e("List Size: ", ""+attractionList.getAttractionList().size()); //List Size: 0 }

Pero si uso el mismo tiempo de registro después, en cualquier botón:

@Override public void onBackPressed(){ Log.e("List Size: ", ""+attractionList.getAttractionList().size()); //List Size: 16 }

Realmente no quiero recuperar datos en cada actividad individual o crear intentos para llevar el objeto entre actividades. ¿Hay alguna manera de que pueda arreglar esto?

PD: Este es mi primer post. Lo siento si no lo he hecho de la manera correcta. Muchas gracias.