【问题标题】:How to make an ArrayList with two Firestore collection?如何用两个 Firestore 集合制作一个 ArrayList?
【发布时间】:2018-07-11 14:39:39
【问题描述】:

我想从我的火石数据库加载 RecyclerView。我的firestore结构是这样的:

用户(收藏)-> user_id(文档)-> 书籍(收藏)
书籍(收藏)-> book_id(文档)

新增:数据库结构图片
enter image description here
enter image description here
enter image description here

我想要做的是将 current_user 的 book_ids 放入 ArrayList<String> 然后使用这个数组列表,对于每个循环,我想将书籍加载到另一个 ArrayList<Book> 中。我正在获取当前用户的“ArrayList book_ids”。 (我想显示当前用户添加的书籍)
问题在于这个数组列表我无法获得ArrayList<Book>books。我会将这个数组列表发送到回收器视图适配器。

        public void getBookIdsFromDb(){
    final ArrayList<String> myBookIds = new ArrayList<String>();

    CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
            .collection(getString(R.string.colleciton_books));

    bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
            if (task.isSuccessful()){
                for (DocumentSnapshot ds : task.getResult()){
                    myBookIds.add(ds.getString("book_id"));
                   myBookIds.size());
                }
                Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
                if (myBookIds.size()>0){
                    getMyBooksFromDb(myBookIds);
                    //this works
                }


            }
        }
    });
}
public void getMyBooksFromDb(ArrayList<String> bookIds){
    final ArrayList<String> myBooksIds =bookIds;
    final ArrayList<Book> myBooks = new ArrayList<Book>();

    CollectionReference dbRef = db.collection(getString(R.string.colleciton_books));
    for (int i =0; i<myBooksIds.size();i++){
        Log.d(TAG, "getMyBooksFromDb: myBookIds in for " + myBooksIds.size());

dbRef.document(myBooksIds.get(i)).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
            @Override
            public void onSuccess(DocumentSnapshot documentSnapshot) {
                if (documentSnapshot != null){
                    Book myBook = documentSnapshot.toObject(Book.class);
                    myBooks.add(myBook);
                    //Can not get out of this array from for loop
                }

            }
        });
    }

}


//I tried to make a nested query below but no result :(

  public void getBookListFromDb(){
    final ArrayList<String> myBookIds = new ArrayList<String>();

    CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
            .collection(getString(R.string.colleciton_books));

    bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
            final ArrayList<Book> myBooks = new ArrayList<Book>();
            if (task.isSuccessful()){
                for (DocumentSnapshot ds : task.getResult()){
                    myBookIds.add(ds.getString("book_id"));
                    myBookIds.size();
                }
                Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
                if (myBookIds.size()>0){
                    CollectionReference colRef = db.collection(getString(R.string.colleciton_books));
                    for (int i=0; i< myBookIds.size(); i++){

                        colRef.document(myBookIds.get(i)).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                            @Override
                            public void onComplete(@NonNull com.google.android.gms.tasks.Task<DocumentSnapshot> task) {
                                if (task.isSuccessful()){
                                    DocumentSnapshot ds = task.getResult();
                                    Book myBook = ds.toObject(Book.class);
                                    myBooks.add(myBook);
                                }

                                Log.d(TAG, "onComplete: myBooks.size(i) "+ myBooks.size());
                            }
                        });
                        Log.d(TAG, "onComplete: myBooks.size() in for "+ myBooks.size());
                    }

                    Log.d(TAG, "onComplete: myBooks.size() "+ myBooks.size());

                }


            }
        }
    });
}'

【问题讨论】:

    标签: android arraylist google-cloud-firestore


    【解决方案1】:

    您无法以这种方式实现您想要的,因为onComplete()onSuccess() 这两种方法都具有异步行为。这意味着当您调用getMyBooksFromDb() 方法时,您还没有完成从数据库中获取数据。因此,要解决这个问题,您需要将所有逻辑从 getMyBooksFromDb() 方法移到 onComplete() 方法中。这是流程:

    • 在您的 bookIdRef 上添加一个完整的侦听器
    • 使用 foo 循环通过迭代获取数据库中的所有 book_id
    • onComplete() 方法中使用book_id 创建您的CollectionReference 以查找书籍。
    • ArrayList&lt;Book&gt; 的声明移到onSuccess() 方法中。
    • 用你的列表或Book 对象做你想做的事。

    因此,解决方案是使用上述嵌套查询。所以请使用以下代码:

    CollectionReference bookIdRef = db.collection(getString(R.string.collection_users))
        .document(userId)
        .collection(getString(R.string.colleciton_books));
    
    bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
            if (task.isSuccessful()){
                for (DocumentSnapshot ds : task.getResult()) {
                    String bookId = myBookIds.add(ds.getString("book_id"));
    
                    dbRef.document(bookId).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                        @Override
                        public void onSuccess(DocumentSnapshot documentSnapshot) {
                            if (documentSnapshot != null){
                                Book myBook = documentSnapshot.toObject(Book.class);
                                Log.d("TAG", myBoog.getBookName());
                            }
                        }
                    });
                }
            }
        }
    });
    

    【讨论】:

    • 嗨,Alex,我无法通过嵌套查询获得价值,你能写一个代码示例吗?谢谢。
    • 请添加详细的数据库结构,以便我给您写一些代码。
    • 我添加了一些显示我的数据库结构的图像。
    • 你是什么时候我推荐你的,有什么问题?你有错误吗?可以分享一下你用过的代码吗?
    • 我没有收到错误,我尝试进行嵌套查询但我不能。我的 ArrayList 总是为 0。我无法从“for loop”中获取值。您可以检查上面的“getBookListFromDb”方法。
    【解决方案2】:

    步骤-1:

    创建Userbook.java 和 Book.java 的模型类

    Userbook.Java
    
    String book_id;
    Book book;
    
    //create getter and setter for that.
    

    根据您的代码设置值:

    UserBook userbook = new UserBook();
    
    final ArrayList<UserBook> books = new ArrayList<String>();
    
    public void getBookIdsFromDb(){
    
    
        CollectionReference bookIdRef = db.collection(getString(R.string.collection_users)).document(userId)
                .collection(getString(R.string.colleciton_books));
    
        bookIdRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull com.google.android.gms.tasks.Task<QuerySnapshot> task) {
                if (task.isSuccessful()){
                    for (DocumentSnapshot ds : task.getResult()){
                       userbook.setBook_id(ds.getString("book_id"));
    
                    }
                    Log.d(TAG, "onComplete: myBookIds.size" + myBookIds.size());
                    if (myBookIds.size()>0){
                        getMyBooksFromDb(myBookIds);
                        //this works
                    }
    
    
                }
            }
        });
    }
    public void getMyBooksFromDb(ArrayList<String> bookIds){
    
        CollectionReference dbRef = db.collection(getString(R.string.colleciton_books));
        for (int i =0; i<myBooksIds.size();i++){
            Log.d(TAG, "getMyBooksFromDb: myBookIds in for " + myBooksIds.size());
            dbRef.document(myBooksIds.get(i)).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                @Override
                public void onSuccess(DocumentSnapshot documentSnapshot) {
                    if (documentSnapshot != null){
                        Book myBook = documentSnapshot.toObject(Book.class);
    
                        userbook.setBook_id(myBook);
                        //Can not get out of this array from for loop
                    }
    
                }
            });
        }
    
    }
    //after all this add obj to list
    books.add(userbook);
    

    我希望你能得到结果。否则在这里ping。

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 1970-01-01
      • 2020-05-25
      • 2021-04-10
      • 2020-07-24
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多