1

Suppose we would like to retrieve 15 random children from questions node having this database structured as below:

enter image description here

1. The first (intuitive and discussed) way of retrieving random children from Firebase is to retrieve the whole required parent node (questions as dataSnapshot) and then select some random children on the client-side. This method has been pointed out in many posts, like in this one here . Obviously, this method has its downsides; for example when querying through a large sized parent node (e.g. over 10.000 children) retrieving such an amount every time would result in a huge bandwidth usage as well as a client side burden. (when we actually require only a small amount of children)

2. Moving on: another approach, as described here which uses an iterator somehow bypasses the whole client side burden, yet the huge bandwidth usage could still occur as we download the whole parent node every time.

3. An interesting approach is described in Tom's answer in this firebase discussion which proposes:

A hacky way of doing this would be to generate a random key and do a query with startAt().limit(1). I have a feeling this could hurt the performance of your firebase though, so this should not be an operation you perform often. We don't have a real random sample function.

This solution actually sounds pretty good, yet I am not sure how it would indeed impact my Firebase.

4. Another silly solution could actually be naming the question ids manually, so to speak, from 0 to N, therefore handling the random group of ids on the client side and retrieving the questions spot-on by knowing the actual name of nodes.

5. And lastly, I have come up with the following solution to which I ask if is more or less viable than the ones presented above: creating another parent containing the question ids only and when needed, one should retrieve this parent which is much "lighter" than questions parent . From there, I would have the specific random ids and I would only need to snipe for those children. To better understand my meaning, please check the below picture: enter image description here

Now, from this method arises the following issue: is assigning (let's say) 15 eventListeners good practice? Could this actually slow up things? (Note: this applies to methods 3 and 4 as well)

And ultimately, which method is actually the optimal one when querying from a large database for some random children?

Community
  • 1
  • 1
Catalin Ghita
  • 794
  • 8
  • 26
  • What do you mean by assigning 15 event listeners? What do you want to do with 15 event listeners? – Hasan Bou Taam Feb 15 '18 at 18:06
  • @svi.data As I might have not made myself clear, I would like to retrieve a number of (let us say 15) random children from a parent. As I said, knowing the exact id of the specific children (described in last method) would imply in assigning 15 listeners. e.g. `databaseRef.child("questions").child("id_0001").addSingleValueEventListener(..)` for each random id I acquired. – Catalin Ghita Feb 15 '18 at 18:11
  • so you are trying to get the details under each random id (so you need to use 15 event listeners)? – Hasan Bou Taam Feb 15 '18 at 18:19
  • @svi.data Yes. I do need to get the details under each random id. – Catalin Ghita Feb 15 '18 at 18:22
  • Then of course you use only one listener pointing to your (question_ids) ref. Which is better. – Hasan Bou Taam Feb 15 '18 at 18:23
  • instead of 15 listeners. – Hasan Bou Taam Feb 15 '18 at 18:24
  • @svi.data I have to do that as that is the source of random ids. As said above, i get all the list of ids and then i select some. After that though, I have to get the information for each id by attaching a listener for each one under `questions` node – Catalin Ghita Feb 15 '18 at 18:32
  • are you listing the (question_ids) in recycler view or a list view? – Hasan Bou Taam Feb 15 '18 at 18:42
  • @svi.data I am not listing the ids. I only need to obtain them so I can attach listeners to them and therefore obtain more information regarding those questions. – Catalin Ghita Feb 15 '18 at 18:45

2 Answers2

1

You can use the classic solution as I explained in this answer but if you are afraid of getting huge amount of data then use instead 15 listeners. There is nothing wrong in using listeners as long as you remove them according to the life-cycle of your activity. So, IMHO go ahead with 15 listeners.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • So you are proposing the 5th solution I presented? In this case, As I remember, Firebase listeners are automatically removed according to a specific life-cycle, therefore there is no need in removing (deattaching) the listeners manually. – Catalin Ghita Feb 16 '18 at 09:28
  • Yes, the 5th solution. No, they are not. Take a look [here](https://stackoverflow.com/questions/47159707/how-to-remove-listener-from-firebase-realtime-database) to see where you need to remove a listener. – Alex Mamo Feb 16 '18 at 09:33
  • I understand and indeed, in this case I should remove the listeners. Therefore, there is no other better solution to this issue? Thank you and I will accept the answer. – Catalin Ghita Feb 16 '18 at 09:40
  • You already mentioned all the ways in which you can solve this problem. Thanks. Cheers! – Alex Mamo Feb 16 '18 at 09:42
0

We have 2 case here

case 1

If you want to grab all details of the random ids at once, then I suggest 1 listener to the parent node (get value of datasnapshot using pojo class).

case 2

If you want to get the details independently upon request then you will have to attach a listener to each (random id) that you want.

Concerning performance

Try to use only Listener For Single Value Events as they listen one time and then stop (better for performance).

Dont use Value Event Listener (because these listeners keep checking for changes and therefore bad performance as listeners increase).

EDIT

lets say you listened to (questions_ids) node, now you have access to the random id keys, store them in a String variable, and then inside the same listener add another listener to (questions) pointing to the id that you want to grab details

      //first listen to question ids ref (the one with 15 ids)

       question_ids_ref.addListenerForSingleValueEvent(...{
       //grab the key of each (random id) and store in variable

        String random_01=......;

        //run another listener this time to questions ref

             questions_ref.child(random_01).addListenerForSingleValueEvent(..{

             //get details of random_01 and so on....

         });



       });
Hasan Bou Taam
  • 4,017
  • 2
  • 12
  • 22
  • At case 1, You mean 1 listener attached to `questions`? In this case, this does not solve my problem. This would fall in the first case I presented which has both issues – Catalin Ghita Feb 15 '18 at 18:56
  • case 1 is 1 listener to (question ids) node .....If you want the details all at once if not then case 2. – Hasan Bou Taam Feb 15 '18 at 18:58
  • Attaching a listener to question_ids only solves half of the problem. I still need to get the details for each random id. – Catalin Ghita Feb 15 '18 at 18:59
  • use pojo class then. – Hasan Bou Taam Feb 15 '18 at 19:00
  • Questions are POJOs. But the content of the questions is only available in `questions` node. Attaching a listener there falls into the first category (first solution presented above). – Catalin Ghita Feb 15 '18 at 19:02
  • Your given example shows how to get info regarding one random id. But the first listener gets all the random ids, and therefore the nested listener you presented should get info on all the random keys. Yet your example works for only 1 random key. Correct me If wrong – Catalin Ghita Feb 15 '18 at 19:54