我正在尝试从Cloud Firestore检索一组复杂的对象。
数据存储如下:
书籍文档包含作者和翻译者子集合。为了检索书籍的完整列表,有一个对数据库的调用,如下所示(我省略了Book对象的所有其他属性,并保留了理解问题的必要条件):
public void getBooks(final BookRetrievable bookRetrievable) {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
ArrayList<Book> books = new ArrayList<>();
firebaseFirestore.collection("books")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Book book = new Book();
book.setId(documentSnapshot.getString("id"));
book.setName(documentSnapshot.getString("name"));
book.setStatus(Status.valueOf(documentSnapshot.getString("status")));
documentSnapshot.getReference().collection("authors")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
ArrayList<Author> authors = new ArrayList<>();
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Author author = new Author();
author.setId(documentSnapshot.getString("id"));
author.setNameInEnglish(documentSnapshot.getString("nameInEnglish"));
author.setNameInSinhalese(documentSnapshot.getString("nameInSinhalese"));
author.setWebsite(documentSnapshot.getString("website"));
authors.add(author);
}
book.setAuthors(authors);
documentSnapshot.getReference().collection("translators")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
ArrayList<Translator> translators = new ArrayList<>();
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Translator translator = new Translator();
translator.setId(documentSnapshot.getString("id"));
translator.setNameInEnglish(documentSnapshot.getString("nameInEnglish"));
translator.setNameInSinhalese(documentSnapshot.getString("nameInSinhalese"));
translator.setWebsite(documentSnapshot.getString("website"));
translators.add(translator);
}
book.setTranslators(translators);
books.add(book);
books.sort((Book b1, Book b2) -> b1.getSeriesNo().compareTo(b2.getSeriesNo()));
bookRetrievable.onCallback(books);
} else {
bookRetrievable.onCallback(null);
}
}
});
} else {
bookRetrievable.onCallback(null);
}
}
});
}
} else {
bookRetrievable.onCallback(null);
}
}
});
}
但是,如果我输入Logs,则似乎回调与检索到的Books一样多。因此,有没有一种方法可以优化此代码,使得每本书只有一个回叫,而每个作者和翻译者文档只有一个回叫?
谢谢!
答案 0 :(得分:1)
是的,有。为了获取所有书籍对象,无需创建Book
类的对象,您可以像这样从DocumentSnapshot
对象中获取它:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference booksRef = rootRef.collection("books");
booksRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
Book book = document.toObject(Book.class);
//Do whay you need to do with your Book object
}
}
}
});
如果您需要获得特定书籍的作者和翻译者,请在您的Book
类中添加另外两个文件author
和translator
以及相应的公开获取者。要说,假设是book对象的翻译器,您可以使用以下代码行:
Translator translator = book.getTranslator();
以与作者相同的方式。
Author autothor = book.getAuthor();