8

I have recently started switching my app from Parse to Firebase. Everything is going great so far, but I have not been able to find a Firebase equivalent method to Parse's whereContainedIn(String key, Collection values).

This was a very useful method that allowed me to pass in an array of ids and it would return all of the rows that matched that id. So far with Firebase, I have it returning all all of the rows in the database then looping through them to see if that row's id is contained in my array of ids. The other way is to query for each id individually, which doesn't work well with Firebase's asynchronous behavior. This is what I am doing now for the first approach:

List<String> userIds = new ArrayList<>();
userIds.add("2");
userIds.add("32");
userIds.add("12545");
userIds.add("187");

DatabaseReference firebaseRef = FirebaseDatabase.getInstance().getReference();
Query queryRef = firebaseRef.child("videos");

queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

        List<Video> usersVideos = new ArrayList<Video>();

        for (DataSnapshot videoSnapshot : dataSnapshot.getChildren()) {
            Video video = videoSnapshot.getValue(Video.class);

            if (userIds.contains(video.userId)) {
                usersVideos.add(video);
            }
        }

        // usersVideos is now populated with the videos for the users

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, "CANCELLED");
    }
});

Neither of these methods seem reasonable since my table will contain hundreds of thousands of records.

Any help would be greatly appreciated!

Mark
  • 1,130
  • 3
  • 17
  • 32
  • 2
    Firebase doesn't have a `WHERE id IN (1,2,3)` equivalent. For reasonably sized lists that is not needed, since Firebase pipelines requests. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 – Frank van Puffelen Aug 08 '16 at 18:21

2 Answers2

1

Make another reference that can be looked up by userId and have it return all videoIds that this user has. From there you can query the videos. That means each time you save you will need to save in two spots. Sort of a pain, but it is what Firebase recommends.

So your reference will look more like:

videos -
       | - <videoId> - 
             | - <video stuffs>
             | - userId
videosByUser -
       | - <userId> -
                    | 0 - <videoIdA>
                    | 1 - <videoIdB>
       | - <userId2> -
                    | 0 - <videoIdA>   
Chad Bingham
  • 32,650
  • 19
  • 86
  • 115
  • 1
    Thanks, but is it possible to return the Video objects instead of just the ids? This would still require a separate query for each video. My goal is to get all of the Video objects for a particular User with one query. – Mark Aug 12 '16 at 13:45
  • You could save the video object in both places. But it would be better to just make another query. – Chad Bingham Aug 12 '16 at 15:26
  • I don't think this answers the original question? – Atticus29 Jul 16 '17 at 04:02
0

can't you just perhaps do a for loop over your ids and inside the for loop write a valueventlistener that will be called for each iterated item`?

chrisma
  • 1
  • 1
  • Please add further details to expand on your answer, such as working code or documentation citations. – Community Aug 30 '21 at 22:15
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). – Vatsal Dholakiya Aug 31 '21 at 13:46