【问题标题】:Retrieving Complex Object from Cloud Firestore Android从 Cloud Firestore Android 中检索复杂对象
【发布时间】:2018-08-05 08:49:10
【问题描述】:

我正在尝试从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) {
                }
            });
}

从数据库中检索保存的值的最佳方法是什么?很难找到一次访问所有值的好方法。我目前使用以下方法来检索除 Authors 和 Translators 之外的值(它们是 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 {
                    }
                }
            });
}

还有什么比这更好的方法吗?请告诉我一次性检索 ArrayList 的最佳方法是什么?

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

提前致谢!

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

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

    您将数据添加到数据中的方式没有错。没有最好的方法来做到这一点。最好的解决方案是适合您的需求并使您的工作更轻松的解决方案。如果您在使用Map 时感觉很舒服,就让代码保持原样。如果您想要另一种方法,我可以为您提供另一种解决方案,即使用模型(POJO)类。这就是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; }
    }
    

    要将此对象添加到数据库中,只需创建一个 Book 类的新对象并将所有这些字段值传递给构造函数。

    还有什么比这更好的方法吗?请告诉我一次性检索 ArrayList 的最佳方法是什么?

    您使用回调从数据库中获取数据的方式是正确的。在这种情况下也没有其他最好的方法,因为您不能作为方法的结果返回 ArrayList。由于 Firebase API 的异步行为,这是很常见的做法。请参阅 here 了解更多详情。

    【讨论】:

    • 感谢 cmets。我实际上非常了解异步行为,需要澄清我所做的是否是错误的,以及是否有更好、更简单的方法来做到这一点。我通过另一个回调检索了我的子集合数据,现在一切似乎都已经到位:)
    猜你喜欢
    • 2019-01-25
    • 2019-02-20
    • 2021-03-06
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    相关资源
    最近更新 更多