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

问题描述 投票:1回答:2

我想从我的firestone db加载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,对于每个循环,我想将书籍加载到另一个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());

                }


            }
        }
    });
}'
android arraylist google-cloud-firestore
2个回答
1
投票

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

  • 在bookIdRef上添加一个完整的监听器
  • 通过迭代使用for循环获取数据库中的所有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());
                        }
                    }
                });
            }
        }
    }
});

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这里。

© www.soinside.com 2019 - 2024. All rights reserved.