Is this the correct way to retrieve data from Firebase?

WhiteGlove :

Introduction

I am doing an app for school and I have choosen Firebase due to their extensive videos and online material that can help you a lot. But problems like these when you are new to something could be solved here by more experienced people.

What I have understood so far

I want to retrieve a random data object from the realtime database from Firebase. I've seen other posts suggesting examples included in the tutorial videos but none seem to work for me:

I have a DB with questions uploaded by the users with the next structure:

(Forget why it says messages instead of questions since I was following their tutorials line by line trying to accomplish my goal)

In order to retrieve data you have to create a reference to the DB as:

//DB Object
private FirebaseDatabase mFirebaseDatabase;
//This will only reference the message part of the DB
private DatabaseReference mQuestionsDBReference;

and the initialize it as:

private void loadQuestionsDB() {
    //Access point
    mFirebaseDatabase = FirebaseDatabase.getInstance(); //Instanciate the object
    mQuestionsDBReference = mFirebaseDatabase.getReference().child("messages"); //Only reference the 
    "messages" part
    //System.out.println("[DEBUG] " + mQuestionsDBReference.getDatabase());
}

(I initialize here everything in a function which is later called by onCreate())

In order to select a random question from the DB I went with this solution:

private void loadRandomQuestion() {

    mQuestionsDBReference.startAt(randomNumber()).limitToFirst(1).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            if(dataSnapshot.getChildrenCount() > 0) {
                System.out.println("[DEBUG-PLAY] Cargando!");
                for(DataSnapshot dataSnap : dataSnapshot.getChildren()){
                    //Something I tried so maybe that was the problem I was facing :(
                    String question = dataSnap.child("-M3qlTuWw9TkD-LwQWYA").child("question").getValue().toString();
                    String answer1 = dataSnap.child("answer1").getValue().toString();
                    String answer2 = dataSnap.child("answer2").getValue().toString();
                    String answer3 = dataSnap.child("answer3").getValue().toString();
                    String answer4 = dataSnap.child("answer4").getValue().toString();

                    questionViewTxt.setText(question);
                    radioButton1.setText(answer1);
                    radioButton2.setText(answer2);
                    radioButton3.setText(answer3);
                    radioButton4.setText(answer4);
                }
            } else {
                System.out.println("[DEBUG] No children :/, that's a problem right there...");
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

Problem and Goal

I can not successfully retrieve a random question from the DB neither the one that I need.

The goal is to be able to retrieve a random question each time I press a Button or call the function loadRandomQuestion().

Notes

- Instead of System.out.println() I could use Log
   - Instead of the above I could use the debugger
   - I know there are multiple listeners for referencedDB
   - I am at beginner level in this subject (3 days since this post)
   - I'm using Andriod Studio
Frank van Puffelen :

Your mQuestionsDBReference.startAt(randomNumber()) won't work, because:

  1. You're not specifying what to order by, so startAt(randomNumber()) will not "know" where to start.
  2. You have no relevant number either as the key or as a property in the JSON, so there's nothing for Firebase to match on.

You seem to think that startAt() can be used with an offset, which is not the case. Firebase startAt()/endAt() queries are cursor based, meaning you need to specify a value to start at.

For example, you could do:

mQuestionsDBReference.orderByKey().startAt("-M3qm...Q2Tz-")...

or start at a specific question with:

mQuestionsDBReference.orderByChild("Question").startAt("¿question?")...

To allow random access:

  1. Add a property with a predictable range of values to each question.
  2. Calculate a random value within that range.
  3. Then order by that property, and start at that value.

Also see:

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=401283&siteId=1