1

I am following this approach to get 3 random documents that are stored in a collection in Firestore.

I am using the first approach to select 3 random categories out of 8, which is working fine. The next step in my app is that the user clicks on one of the 3 categories and by that it should get 3 random questions from the selected category and display it in the Fragments that come after the "Category Selection" fragment. I noticed that I cannot use the first approach since that would end up in a huge number of reads since, in the end, every category will have at least 500 questions.

Apparently there is a more efficient way to get random questions (second approach), but I have a hard time understanding it. It says that I should create another document as an array which can hold all question ids inside but how do I add all the question ids into this array? I don't know how eventually the code would look like.

Here is the way I stored my questions: enter image description here

When I understood the second approach right I have to store all the ids from the questions in a document as an array, but how do I get all of the ids into the array? Is there another approach other than using cloud functions? So what I need is a code implementation of the second approach described in the link from above or an example on how to implement the approach.

Any help is much appreciated!

Here is the code I have for the approach:

...
questionRef.document(tvCat1).collection(tvCat1).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {

                            List<Questions> questionsList = new ArrayList<>();
                            for (DocumentSnapshot document : task.getResult()) {
                                Questions question = document.toObject(Questions.class);
                                questionsList.add(question);
                            }

                            int questionListSize = questionsList.size();
                            List<Questions> randomQuestionsList = new ArrayList<>();
                            for (int i = 0; i < questionListSize; i++) {
                                Questions randomQuestions = questionsList.get(new Random().nextInt(questionListSize));
                                if (!randomQuestionsList.contains(randomQuestions)) {
                                    randomQuestionsList.add(randomQuestions);
                                    if (randomQuestionsList.size() == 3) {

                                        Collections.shuffle(questionsList);

                                        question1 = questionsList.get(0).getQuestion();
                                        question2 = questionsList.get(1).getQuestion();
                                        question3 = questionsList.get(2).getQuestion();

                                        answer1 = questionsList.get(0).getAnswer();
                                        answer2 = questionsList.get(1).getAnswer();
                                        answer3 = questionsList.get(2).getAnswer();
...
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Kaiser
  • 606
  • 8
  • 22

1 Answers1

3

Apparently there is a more efficient way to get random questions (second approach)

Actually, I answered that question, and yes, that's correct. The second approach is more efficient.

It says that I should create another document as an array that can hold all question ids inside but how do I add all the question ids into this array?

There are two ways in which you can achieve this. The first one would be to add the id of the question in the array as you create the question database. This means that every time you add a new question to the database, add its corresponding id to that array. This can be done using a line of code that should look similar to this:

documentRef.update("questions", FieldValue.arrayUnion("newQuestionId"));

When I understood the second approach right I have to store all the ids from the questions in a document as an array, but how do I get all of the ids into the array?

Second approach, if you already have added all questions to the database, then you should iterate through the collection of questions, get all documents IDs and create that array. Please note also one more thing, once you populate the array with all the IDs when you want to add another question, you should again use solution one, to keep the questions from the collection in sync with your array.

Is there another approach other than using cloud functions?

You can also use Cloud Functions if you'll like. I just showed you how you can solve that on the client.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193