I am trying to retrieve a set of complex objects from a Cloud Firestore
database. Here is my class:
public class Book {
private String id;
private String name;
private String original;
private ArrayList<Author> authors;
private ArrayList<Translator> translators;
private Series series;
private Float no;
private String seriesNo;
private Integer published;
private Borrower borrower;
private Boolean isCollection;
private Status status;
}
What is the best way to save this Book
object to the database? I am currently using the following method.
public void createBook(String userId) {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
DocumentReference documentReference = firebaseFirestore.collection("books").document();
Map<String, Object> newBook = new HashMap<>();
newBook.put("owner", userId);
newBook.put("id", documentReference.getId());
newBook.put("name", getName());
newBook.put("original", getOriginal());
if (getSeries() != null) {
Map<String, Object> series = new HashMap<>();
series.put("id", getSeries().getId());
series.put("name", getSeries().getName());
newBook.put("series", series);
}
newBook.put("no", getNo());
newBook.put("seriesNo", getSeriesNo());
newBook.put("published", getPublished());
if (getBorrower() != null) {
Map<String, Object> borrower = new HashMap<>();
borrower.put("id", getBorrower().getId());
borrower.put("nameInEnglish", getBorrower().getNameInEnglish());
borrower.put("nameInSinhalese", getBorrower().getNameInSinhalese());
borrower.put("mobile", getBorrower().getMobile());
newBook.put("borrower", borrower);
}
newBook.put("isCollection", getIsCollection());
newBook.put("status", getStatus().toString());
documentReference
.set(newBook)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
for (int i = 0; i < getAuthors().size(); i++) {
documentReference.collection("authors").document("author" + i)
.set(getAuthors()
.get(i));
}
for (int i = 0; i < getTranslators().size(); i++) {
documentReference.collection("translators").document("translator" + i)
.set(getTranslators()
.get(i));
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
}
});
}
What is the best way to retrieve the saved values from the database? It's hard to find a good way to access all the values at once. I currently use the following method to retrieve the values excepts for Authors and Translators (which are ArrayLists).
public void getBooks(final BookRetrievable bookRetrievable, String userId) {
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.setOriginal(documentSnapshot.getString("original"));
Series series = new Series();
series.setId(documentSnapshot.getString("series.id"));
series.setName(documentSnapshot.getString("series.name"));
book.setSeries(series);
book.setNo(documentSnapshot.getDouble("no").floatValue());
book.setSeriesNo(documentSnapshot.getString("seriesNo"));
book.setPublished(documentSnapshot.getLong("published").intValue());
Borrower borrower = new Borrower();
borrower.setId(documentSnapshot.getString("series.id"));
borrower.setNameInEnglish(documentSnapshot.getString("series.nameInEnglish"));
borrower.setNameInSinhalese(documentSnapshot.getString("series.nameInSinhalese"));
borrower.setFacebook(documentSnapshot.getString("series.facebook"));
borrower.setMobile(documentSnapshot.getString("series.mobile"));
book.setBorrower(borrower);
book.setIsCollection(documentSnapshot.getBoolean("isCollection"));
book.setStatus(Status.valueOf(documentSnapshot.getString("status")));
books.add(book);
}
books.sort((Book b1, Book b2) -> b1.getName().compareTo(b2.getName()));
bookRetrievable.onCallback(books);
} else {
}
}
});
}
Is there anything that I can do better than this and please let me know what is the best way to retrieve ArrayLists in one go?
For easier understanding, I have added screenshots of an example already saved in the database:
Thanks in advance!