marcuthh
marcuthh

Reputation: 596

Firebase - query on nested key?

I'm running an Android app that handles some data on Events and Users who have been invited to them. I have a page that needs to show all the events that a user has been invited to, but I'm relatively new to Firebase and I'm not sure how the query syntax would work for my current data structure.

An example of my data-structure (with dummy keys) can be seen below:

events
    event1_key
        eventName: "test event"
        eventAdmin: "userAdmin"
        eventInvites
            user1_key
                attending: true
                responseTimestamp: 1525416294951
            user2_key
                //...
    event2_key
        //...
        eventInvites
            user2_key
                //...
            user3_key
                //...

So using this example, if I was looking for all the events that user1_key had been invited to, the query should only return the event1_key record, because that one has a nested eventInvite for user1_key.

If I'm running that query in Java for Android Studio, does anybody know what it should look like?

Upvotes: 0

Views: 306

Answers (2)

Alex Mamo
Alex Mamo

Reputation: 139019

To achieve what you want, I recommend add another node in your database structure that looks like this:

Firebase-root
    |
    --- userEvents
           |
           --- user1_key
                 |
                 --- event1_key: true
                 |
                 --- event2_key: true

In this way you'll be able to read all your events that correspond to a particular user at once without the need to download the enitire events object. To get those ids, please use the following code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userKeyRef = rootRef.child("userEvents").child(userKey);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String eventKey = ds.getKey();
            Log.d("TAG", eventKey);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
userKeyRef.addListenerForSingleValueEvent(valueEventListener);

Upvotes: 1

Reaz Murshed
Reaz Murshed

Reputation: 24241

I think you need to replicate your data in another node in this case. Right now, you have a single node which keeps all the events (i.e. events node). I would suggest your create a separate table (i.e. separate node) for users as well.

That node structure might look like the following.

users 
    user1_key
        events1_key
        events2_key
        ... 
    user2_key
        events5_key
        events2_key
        ....
    ....

I this way you will not require any nested lookup. Just replicate the data here in this node as well when you are inserting the data under events node.

Hope that helps!

Update

If you are considering replicating your table, then the check for user is attending an event will be fairly simple like the following.

userRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        boolean attending = false; 
        for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
            if(eventSnapshot.getKey().equals(THE_DESIRED_EVENT)) {
                attending = true; 
                break;
            }
        }

        if(attending) doSomethingAsUserIsFoundToBeAttendingTheEvent();
        else userIsNotAttending();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

The code is not tested, I just have the pseudo implementation. Please modify as per your need.

Upvotes: 1

Related Questions