Firebase Firestore получает данные из коллекции
Я хочу получить данные из моей базы данных Firebase Firestore. У меня есть коллекция под названием user, и у каждого пользователя есть коллекция некоторых объектов того же типа (мой пользовательский объект Java). Я хочу заполнить свой ArrayList этими объектами при создании моей активности.
private static ArrayList<Type> mArrayList = new ArrayList<>();;
В onCreate():
getListItems();
Log.d(TAG, "onCreate: LIST IN ONCREATE = " + mArrayList);
*// it logs empty list here
Метод, вызываемый для получения элементов в список:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(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());
DocumentReference documentReference1 = FirebaseFirestore.getInstance().document("some path");
documentReference1.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(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(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
Переведено автоматически
Ответ 1
get()
Операция возвращает a Task<>
, что означает, что это асинхронная операция. Вызов getListItems()
только запускает операцию, он не ждет ее завершения, вот почему вы должны добавить прослушиватели успеха и сбоя.
Хотя вы мало что можете сделать с асинхронным характером операции, вы можете упростить свой код следующим образом:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(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(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
Ответ 2
Попробуйте это..Работает нормально.Приведенная ниже функция также будет получать обновления в реальном времени от firebse..
db = FirebaseFirestore.getInstance();
db.collection("dynamic_menu").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e !=null)
{
}
for (DocumentChange documentChange : documentSnapshots.getDocumentChanges())
{
String isAttendance = documentChange.getDocument().getData().get("Attendance").toString();
String isCalender = documentChange.getDocument().getData().get("Calender").toString();
String isEnablelocation = documentChange.getDocument().getData().get("Enable Location").toString();
}
}
});
Дополнительная ссылка
:https://firebase.google.com/docs/firestore/query-data/listen
Если вы не хотите получать обновления в реальном времени, обратитесь к Нижеприведенному документу
https://firebase.google.com/docs/firestore/query-data/get-data
Ответ 3
Вот упрощенный пример:
Создайте коллекцию "DownloadInfo" в Firebase.
И добавляет в нее несколько документов с этими полями:
имя_файла (строка), идентификатор (строка), размер (число)
Создайте свой класс:
public class DownloadInfo {
public String file_name;
public String id;
public Integer size;
}
Код для получения списка объектов:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("DownloadInfo")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
if (task.getResult() != null) {
List<DownloadInfo> downloadInfoList = task.getResult().toObjects(DownloadInfo.class);
for (DownloadInfo downloadInfo : downloadInfoList) {
doSomething(downloadInfo.file_name, downloadInfo.id, downloadInfo.size);
}
}
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
Ответ 4
Это код для получения списка. Поскольку это асинхронная задача, это требует времени, поэтому размер списка сначала отображается пустым. Но включение источника данных кэша позволит предыдущему списку (а также его размеру) оставаться в памяти до выполнения следующей задачи.
Source source = Source.CACHE;
firebaseFirestore
.collection("collectionname")
.get(source)
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
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);
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});