Я хочу получить данные из моей базы данных Firebase Firestore. У меня есть коллекция под названием user, и у каждого пользователя есть коллекция некоторых объектов того же типа (мой пользовательский объект Java). Я хочу заполнить свой ArrayList этими объектами при создании моей активности.
getListItems(); Log.d(TAG, "onCreate: LIST IN ONCREATE = " + mArrayList); *// it logs empty list here
Метод, вызываемый для получения элементов в список:
privatevoidgetListItems() { mFirebaseFirestore.collection("some collection").get() .addOnSuccessListener(newOnSuccessListener<QuerySnapshot>() { @Override publicvoidonSuccess(QuerySnapshot documentSnapshots) { if (documentSnapshots.isEmpty()) { Log.d(TAG, "onSuccess: LIST EMPTY"); return; } else { for (DocumentSnapshot documentSnapshot : documentSnapshots) { if (documentSnapshot.exists()) { Log.d(TAG, "onSuccess: DOCUMENT" + documentSnapshot.getId() + " ; " + documentSnapshot.getData()); DocumentReferencedocumentReference1= FirebaseFirestore.getInstance().document("some path"); documentReference1.get().addOnSuccessListener(newOnSuccessListener<DocumentSnapshot>() { @Override publicvoidonSuccess(DocumentSnapshot documentSnapshot) { Type type= documentSnapshot.toObject(Type.class); Log.d(TAG, "onSuccess: " + type.toString()); mArrayList.add(type); Log.d(TAG, "onSuccess: " + mArrayList); /* these logs here display correct data but when I log it in onCreate() method it's empty*/ } }); } } } } }).addOnFailureListener(newOnFailureListener() { @Override publicvoidonFailure(@NonNull Exception e) { Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show(); } }); }
Переведено автоматически
Ответ 1
get()Операция возвращает a Task<>, что означает, что это асинхронная операция. Вызов getListItems() только запускает операцию, он не ждет ее завершения, вот почему вы должны добавить прослушиватели успеха и сбоя.
Хотя вы мало что можете сделать с асинхронным характером операции, вы можете упростить свой код следующим образом:
privatevoidgetListItems() { mFirebaseFirestore.collection("some collection").get() .addOnSuccessListener(newOnSuccessListener<QuerySnapshot>() { @Override publicvoidonSuccess(QuerySnapshot documentSnapshots) { if (documentSnapshots.isEmpty()) { Log.d(TAG, "onSuccess: LIST EMPTY"); return; } else { // Convert the whole Query Snapshot to a list // of objects directly! No need to fetch each // document. List<Type> types = documentSnapshots.toObjects(Type.class);
// Add all to your list mArrayList.addAll(types); Log.d(TAG, "onSuccess: " + mArrayList); } }) .addOnFailureListener(newOnFailureListener() { @Override publicvoidonFailure(@NonNull Exception e) { Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show(); } }); }
Ответ 2
Попробуйте это..Работает нормально.Приведенная ниже функция также будет получать обновления в реальном времени от firebse..
Это код для получения списка. Поскольку это асинхронная задача, это требует времени, поэтому размер списка сначала отображается пустым. Но включение источника данных кэша позволит предыдущему списку (а также его размеру) оставаться в памяти до выполнения следующей задачи.
return; } else { // Convert the whole Query Snapshot to a list // of objects directly! No need to fetch each // document. List<ModelClass> types = documentSnapshots.toObjects(ModelClass.class); // Add all to your list mArrayList.addAll(types); }