从Cloud Firestore Android检索复杂对象

时间:2018-08-05 08:49:11

标签: java android firebase google-cloud-firestore

我正在尝试从Cloud Firestore数据库中检索一组复杂的对象。这是我的课程:

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;
}

将此Book对象保存到数据库的最佳方法是什么?我目前正在使用以下方法。

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) {
                }
            });
}

从数据库中检索保存的值的最佳方法是什么?很难找到一次访问所有值的好方法。我目前使用以下方法来检索“作者”和“翻译者”(即ArrayList)之外的值。

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 {
                    }
                }
            });
}

还有什么我可以做得更好的,请让我知道一次检索ArrayList的最佳方法是什么?

为了便于理解,我添加了已经保存在数据库中的示例的屏幕截图:

example book saved in database - 1

example book saved in database - 2

谢谢!

1 个答案:

答案 0 :(得分:2)

  

将此Book对象保存到数据库的最佳方法是什么?

将数据添加到数据的方式没有错。没有最好的方法。最好的解决方案是适合您的需求并使您的工作更轻松的解决方案。如果您在使用 this.affectedAccount = Integer.parseInt(tuple.getStringByField("affectedAccount")); 时感到舒适,请按原样编写代码。如果需要其他方法,我可以为您提供另一个解决方案,即使用模型(POJO)类。您的Map类应该是这样的:

Book

要将这个对象添加到数据库中,只需创建一个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; public Book() {} public Book(String id, String name, String original, ArrayList<Author> authors, ArrayList<Translator> translators, Series series, Float no, String seriesNo, Integer published, Borrower borrower, Boolean isCollection, Status status) { this.id = id; this.name = name; this.original = original; this.authors = authors; this.translators = translators; this.series = series; this.no = no; this.seriesNo = seriesNo; this.published = published; this.borrower = borrower; this.isCollection = isCollection; this.status = status; } public String getId() { return id; } public String getName() { return name; } public String getOriginal() { return original; } public ArrayList<Author> getAuthors() { return authors; } public ArrayList<Translator> getTranslators() { return translators; } public Series getSeries() { return series; } public Float getNo() { return no; } public String getSeriesNo() { return seriesNo; } public Integer getPublished() { return published; } public Borrower getBorrower() { return borrower; } public Boolean getCollection() { return isCollection; } public Status getStatus() { return status; } } 类的新对象,并将所有这些字段值传递给构造函数。

  

还有什么我可以做得更好的,请让我知道一次检索ArrayList的最佳方法是什么?

使用回调从数据库获取数据的方式是正确的。在这种情况下,也没有其他最佳方法,因为您不能通过方法返回Book。由于Firebase API的异步行为,这是相当普遍的做法。请参见 here