I am making and application that show a first screen with a bunch of randomly picked data from a node in Firebase database.

To present user with different data every time is kind of important for my application

Is there anyway to achieve this in native Android, all snapshots are of same model


Solution 1:

There is no direct way provided by firebase database but you can do this using Collections.shuffle()

What i did was,Take the snapshot and store it in an arraylist.

 private ArrayList<Integer> array=new ArrayList<>();

    public void onDataChange(DataSnapshot dataSnapshot) {
                        for (DataSnapshot imageSnapshot : dataSnapshot.getChildren()) {
                           MyClass myclass = imageSnapshot.getValue(MyClass.class);
                           array.add(myclass.someFunction());
                        }
}

Then call the shuffle method on this array list.

Collections.shuffle(array); // randomize the arraylist

Now you can do whatever you want with this randomized arraylist.

Solution 2:

Don't think there is a way to randomly grab data from the Firebase database as all queries that you can construct end up being deterministic in some way, either based on the generated push ids (which in turn are based on time) or some other key ordered lexicographically. I think the best way would be to grab a list of data from a node and randomly choose the data client side.

Solution 3:

There actually is a possibility to do that without Loading the whole list client side. First you have to generate a numeric id either as child id or as an extra node. That how your database would look like:

   notes:
  -KXe8LJJzczEJs3YYwRe
     numericid : 001
  -KXeePWrWBXvpw4g9n0p
     numericid : 002

or

   notes:
  001
  002

to create the numbers as String you can use DecimalFormat

String newint = new DecimalFormat("000").format(oldint);

Now you can get the children count in your valueeventlistener an use Math.random() to get a random child, e.g. for the second Database Design

 FirebaseDatabase().getInstance().getReference().child("notes").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Long childrencount = dataSnapshot.getChildrenCount();
                if(childrencount.equals(0))return;
                int random = getRandomInteger(safeLongToInt(childrencount), 1);
                String selectedchild = new DecimalFormat("000").format(random);

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

You also need to add these safeLongtoInt and getRandomInteger

 public static int getRandomInteger(int maximum, int minimum){
    return ((int) (Math.random()*(maximum - minimum))) + minimum;
}
 public static int safeLongToInt(long l) {
    if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
        throw new IllegalArgumentException
                (l + " cannot be cast to int without changing its value.");
    }
    return (int) l;
}

selectedchild is your random child id.