如何使用两个Firestore集合创建一个ArrayList?

时间:2018-02-01 09:59:05

标签: android arraylist google-cloud-firestore

我想从我的firestone db加载RecyclerView。我的firestore结构是这样的:

用户(收藏) - > user_id(document) - >书籍(集合)
书籍(收藏) - > book_id(文件)

补充:数据库结构图像
enter image description here
enter image description here
enter image description here

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

        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());

                }


            }
        }
    });
}'

2 个答案:

答案 0 :(得分:1)

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

  • 在bookIdRef上添加完整的侦听器
  • 使用foor loop
  • 通过迭代获取数据库中的所有book_id
  • onComplete()方法内使用book_id创建CollectionReference来查找图书。
  • 移动ArrayList<Book>方法内的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());
                        }
                    }
                });
            }
        }
    }
});

答案 1 :(得分:0)

步骤-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。