2

I have set up an activity for my users to input messages into Firebase database and another activity to recall the messages at random. However I couldn't seem to get the random method going... the recall method just call the same messages over and over again on click.

I am using and editing the method that username nothingness posted here get random value android firebase java so I don't actually understand how it works...

Here's the code to write to the database:

public class PostActivity extends AppCompatActivity {

    private EditText PostField;
    private Button postSubmit;
    private DatabaseReference mDatabasePosts;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post);

        postSubmit = (Button)findViewById(R.id.postSubmit);
        postField = (EditText)findViewById(R.id.postField);
        mDatabasePosts = FirebaseDatabase.getInstance().getReference().child("posts");

        postSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startPosting();
            }

            private void startPosting() {
                final String postVal = postField.getText().toString().trim();
                if (!TextUtils.isEmpty(postVal)) {

                    //post creation
                    DatabaseReference newPost = mDatabasePosts.push();
                    newPost.setValue(postVal);
                    Toast.makeText(PostActivity.this, "Post registered", Toast.LENGTH_SHORT).show();

                    startActivity(new Intent(PostActivity.this, HomeActivity.class));
                }
            }
        });
    }
}

nothing fancy there...

on the retrieving activity, I have a button that will display a toast randomly (well... at least the goal was to) of the texts written to the database... here's the code for that activity:

DatabaseReference mPost;

mPost = FirebaseDatabase.getInstance().getReference().child("posts");

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                mPost.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        long allNum = dataSnapshot.getChildrenCount();
                        int maxNum = (int)allNum;
                        int randomNum = new Random().nextInt(maxNum);

                        int count = 0;
                        Iterable<DataSnapshot> ds = dataSnapshot.getChildren();
                        Iterator<DataSnapshot> ids = ds.iterator();
                        String newPost = (String) ids.next().getValue();
                        while(ids.hasNext() && count < randomNum) {
                            ids.next();
                            count ++; // used as positioning.
                        }

                        Toast.makeText(HomeActivity.this, newPost,Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
            }
        });

The Database looks like this:

posts
  L random key: "text 1"
  L random key: "text 2"
  L random key: "text 3"
  L random key: "text 4"
  L random key: "text 5"
  L random key: "text 6"

So at the moment, everytime i click on the button... it keeps on calling "text 1" I want it to call text 1 and 2 alternately and randomly...

Can anyone help me with this?

Community
  • 1
  • 1
Jagmaster
  • 107
  • 4
  • 12

2 Answers2

1

The Database looks like this:

    posts
      L random key: "text 1"
      L random key: "text 2"

So at the moment, everytime i click on the button... it keeps on calling "text 1" I want it to call text 1 and 2 alternately and randomly...

You are using:

int randomNum = new Random().nextInt(maxNum);

where maxNum = 2 since you have 2 children in your database.

As the documentation says, this method call returns "a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)".
This means that you will get numbers from 0 to 1 in your case.

Since you are doing this:

while(ids.hasNext() && count < randomNum) {

you are iterating from 0 to 1, it means only the text1 item.

Generally speaking, if you need to generate numbers from min to max (including both), you write

random.nextInt(max - min + 1) + min
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • Thanks so much for your help. I am adding more children to the "posts" child but to no avail... i am still getting the first child's value only Am I doing this correctly? `long allNum = dataSnapshot.getChildrenCount(); int maxNum = (int)allNum; int minNum = 1; int randomNum = new Random().nextInt(maxNum - minNum + 1) + minNum; int count = 0` many thanks! – Jagmaster Feb 17 '17 at 09:15
  • Sorry... tried following the formatting for comments but still can't get the code format right... – Jagmaster Feb 17 '17 at 09:16
  • I don't understand this line Iterator ids = ds.iterator(); How many items has the iterator? – Gabriele Mariotti Feb 17 '17 at 11:04
  • To be honest i don't understand that part either. I was researching on how to get random child's value of Firebase Database and the link I gave above was just one of the many many examples that I came across. I am not even sure if this is the most advisable and efficient way to do it. Basically all I want to do is get text 1, text 2, text 3, text 4, randomly on button click. Of course my users will then add more values – Jagmaster Feb 17 '17 at 12:17
  • But it is very important. You are iterating on this variable (ids) but the post items is the other iterator (ds). Are you sure that this iterator (ids) does contain more items than 1? I should know your db to answer. – Gabriele Mariotti Feb 17 '17 at 12:24
  • Hi Gabriele, sorry I really don't know how iterator works and how it is used... I really just stumbled upon the post and applied it to my code... but here is a snapshot of the database if that's what you mean by 'db'. [link](http://i.imgur.com/IjglvIB.jpg). so the number of items will keep on adding as my users write to the databse. the name "boosts" is not a typo... i simply changed it to post when i posted the question to make it easier to understand... Thank you. – Jagmaster Feb 17 '17 at 12:41
  • Hi Gabriele, so I was doing a little bit of reading about Java Iterable/Iterator just to get a sense of it. So if I am not mistaken, the line `Iterable ds = dataSnapshot.getChildren();` should return me the children of the Datasnapshot (which in this case the children of boosts) and then the line `Iterator ids = ds.iterator();` then get the values (which in this case 'text 1', 'text 2', 'text 3' and so on) ? – Jagmaster Feb 17 '17 at 23:51
  • No you can debug it. The first iterator give you all "posts". for `(DataSnapshot postSnapshot: dataSnapshot.getChildren()) { // TODO: handle the post }`. Then you can access all data inside the post. – Gabriele Mariotti Feb 18 '17 at 09:09
  • Hi I managed to solve it... gonna post the solution now... I simply should have put the `newPost = (String) ids.next().getValue();` inside the while to loop... But thank you for your answer it was really helpful as well... +1 for it :) – Jagmaster Feb 18 '17 at 14:47
0

so in case anyone is also trying to get random values from a dataset from Firebase Database, here's how you do it

  DatabaseReference mPost;

    mPost = FirebaseDatabase.getInstance().getReference().child("posts");

    button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    mPost.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            long allNum = dataSnapshot.getChildrenCount();
                            int maxNum = (int)allNum;
                            int minNum = 1;
                            int randomNum = new Random().nextInt(maxNum - minNum + 1) + minNum;

                            int count = 0;
                            Iterable<DataSnapshot> ds = dataSnapshot.getChildren();
                            Iterator<DataSnapshot> ids = ds.iterator();
                            String newPost = "";

                            while(ids.hasNext() && count < randomNum) {
                                newPost = (String) ids.next().getValue();
                                count ++; // used as positioning.
                            }
                            //String msg = newPost.get("boosts").toString();
                            Toast.makeText(HomeActivity.this, newPost,Toast.LENGTH_LONG).show();
}

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }
            });
Jagmaster
  • 107
  • 4
  • 12