简体   繁体   中英

Retrieve random data from firebase database with options

I am making an Quiz app wherein questions and answers are taken from firebase. I have uploaded questions with its options in firebase and now want to retrieve them randomly but don't know how to do so as I am a beginner in programming. This is the Screenshot of my firebase data

https://drive.google.com/file/d/1T7-x3TP1TaA8_ntwfoRNdb2oMGV_swl6/view?usp=sharing

 private void updateQuestion(){

       mQuestionRef = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/question");

        mQuestionRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

            String question = dataSnapshot.getValue(String.class);
                mQuestionView.setText(question);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });


        mChoiceRef1 = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/choice1");

        mChoiceRef1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String choice1 = dataSnapshot.getValue(String.class);
                mButtonChoice1.setText(choice1);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });

        mChoiceRef2 = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/choice2");

        mChoiceRef2.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String choice2 = dataSnapshot.getValue(String.class);
                mButtonChoice2.setText(choice2);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });

        mChoiceRef3 = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/choice3");

        mChoiceRef3.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String choice3 = dataSnapshot.getValue(String.class);
                mButtonChoice3.setText(choice3);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });

        mChoiceRef4 = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/choice4");

        mChoiceRef4.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String choice4 = dataSnapshot.getValue(String.class);
                mButtonChoice4.setText(choice4);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });

        mAnswerRef = new Firebase("https://testapp-465fe.firebaseio.com/"+ mQuestionNumber + "/answer");

        mAnswerRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

               mAnswer = dataSnapshot.getValue(String.class);

            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });


            mQuestionNumber++;


   }

This is my code to load questions sequentially from the firebase! I googled a lot but not getting how to generate a random node and get the child values of that random node!

Being a beginner, generating random number can be a small mess. So an easy way to do this would be getting the current time in millisecond so that it looks something like 11023049 (hour-min-sec-ms)

Since this would be unique each time it is generated, you would need a function to determine an order of question retrieved based on this unique value.

To be specific to your question, you can just get the time in millisecond , as it is the fastest changing variable and retrieve the question whose number is equal to millisecond. Or to have some variation, odd millisecond values would fetch questions in reverse order, and even values would fetch in normal order .

UPDATE 1 : A trivial way of creating an order is (This would only randomize the starting question, next questions will be in order so other methods are strongly recommended):

public void ArrayList<Integer> getOrderTrivial(int lastQsNum)
{
    System.out.println("Started");
    int currentSec = Integer.parseInt(new SimpleDateFormat("ss").format(new Date()));
    int count = 0;
    ArrayList<Integer> order = new ArrayList<Integer>();
    if (currentSec%2 == 0)
    {
        /*If the second value is even, the order of questions will be straight*/
        for (int i=currentSec; i<=lastQsNum; i++)
        {
            order.add(i);               
        }
        for (int i=0; i<=currentSec; i++)
        {
            order.add(i);               
        }
    }
    else
    {
        /*If the second value is even, the order of questions will be reverse*/
        for (int i=currentSec; i>=0; i--)
        {
            order.add(i);               
        }
        for (int i=lastQsNum; i>=currentSec; i--)
        {
            order.add(i);               
        }           
    }
    System.out.println("Complete");
    return order;
}

UPDATE 2: A better way (recommended)

public ArrayList<Integer> getOrder(int lastQsNum)
{
    ArrayList<Integer> order = new ArrayList<>();
    int sec = Integer.parseInt(new SimpleDateFormat("ss").format(new Date()));
    int start = sec, down = sec - 1, up = sec + 1;      
    order.add(start);
    while (up<=lastQsNum && down>=0)
    {                       
        if (!order.contains(up)) order.add(up);         
        if (!order.contains(down)) order.add(down);
        up = up+1;
        down = down-1;                              
    }       
    if (up>lastQsNum)
    {
        System.out.println("Upper Limit Reaached: "+up+"-"+down);
        int mid = down/2;
        if (!order.contains(mid)) order.add(mid);
        up = mid+1;
        down = mid -1;          
    }
    else if (down<0)
    {
        System.out.println("Lower Limit Reaached: "+up+"-"+down);
        int mid = up + ((lastQsNum - up)/2);
        if (!order.contains(mid)) order.add(mid);
        up = mid+1;
        down = mid -1;
    }
    while (up<=lastQsNum && down>=0)
    {
        if (sec%3 == 0)
        {
            if (!order.contains(up)) order.add(3, up);          
            if (!order.contains(down)) order.add(6, down);
        }
        else if (sec%5 == 0)
        {
            if (!order.contains(up)) order.add(5, up);          
            if (!order.contains(down)) order.add(10, down);
        }
        else if (sec%7 == 0)
        {
            if (!order.contains(up)) order.add(7, up);          
            if (!order.contains(down)) order.add(14, down);
        }
        else if (sec%11 == 0)
        {
            if (!order.contains(up)) order.add(11, up);         
            if (!order.contains(down)) order.add(22, down);
        }
        else if (sec%2 == 0)
        {
            if (!order.contains(up)) order.add(0, up);          
            if (!order.contains(down)) order.add(0, down);  
        }
        else
        {
            if (!order.contains(up)) order.add(up);         
            if (!order.contains(down)) order.add(down);
        }           
        up = up+1;
        down = down-1;          
    }
    return order;
}

The return object for both methods is an ArrayList. In the onCreate() stub of your Activity, you should run this function and create an ArrayList. Something like:

//Global Variables
ArrayList<Integer> order;
int maxQuestions = 200;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    order = getOrderTrivial(maxQuestions);
}

Once the ArrayList called order is created you can serially traverse through the ArrayList and get the question number and use it to fetch question from Firebase Database (from a ValueEventListener).

I have been thinking how to do this and i have come to this

first you will need to fetch all the data from the Database , for this just do like below

  DatabaseReference ref= FirebaseDatabase.getInstance().getReference();


         //Since you dont have a parent for all the questions, you should reference to your url to get all the items
           ref.child("https://testapp-465fe.firebaseio.com/").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                questionList = new ArrayList<String>();                
                // Result will be holded Here
                for (DataSnapshot ql : dataSnapshot.getChildren()) {
                      questionList.add(String.valueOf(ql.geValue())); //We add all the results to an arraylist

                    }
        /* Now all the data from your database will be stored in the ArrayList, just go and get from there what you need, the answers, the questions, etc */

I will leave you this snippet on how to get the content from the ArrayList

 /*This method retrieves values from ArrayList using Iterator
     */
    public static void retrieveValuesFromList(List list)
    {
        Iterator itr = list.iterator();
        while(itr.hasNext())
        {
            System.out.println(itr.next()); //you can use a Log.e("Data: ",""+itr.next()); here
        }
    }

where list will be your ArrayList questionList

retrieveValuesFromList(yourlist);

Hope this helps

happy coding !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM