2

I've the below JSON structure for my application.

root
 |
 +-- groups
 |      |
 |      +-- $gid
 |            |
 |            +-- uids : [$uid1, $uid2,....,$uidN]
 |           
 |      
 +-- users
       |
       +-- $uid
             |
             +-- name: "<name>",
               status: "<status>",
               avatar: "<url>"

How to find the gid that matches specified uids?

The method I was trying concatenated all the uids together with underscores in between.

String mGroupId = mGroupRef.push().getKey();
mGroupRef.child(mGroupId).setValue(new GroupModel(user1.getUid(), user2.getUid()));

class GroupModel {
    private static final String SEPARATOR = "_";
    private String uids;

    public GroupModel(String uid, String uid1) {
            uids = uid + SEPARATOR + uid1;
    }
}

Apparently, this is not a good work.

Because, the question makes it very harder to find the gid since the order of the uids are undefined.

Any notion or a help would be highly appreciated.

Samuel Robert
  • 10,106
  • 7
  • 39
  • 60

1 Answers1

1

Firebase queries can only contain a single orderBy/filter clause. If you want to search for multiple criteria, you will need to find a way to either combine the values of the criteria into a single property or a data model that allows the query.

In your scenario combining the UIDs into a single string seems the most direct mapping to me. Just order the UIDs alphabetically (or any way that guarantees they're always in the same order) and then concatenate the strings.

I've written about this before in Best way to manage Chat channels in Firebase, which also contains a runnable code snippet.

If a group is defined by its members (as it is in many chat scenarios), then you could event use the concatenated UIDs as the room key. If you have many members that key might get longer than what Firebase allows, so it's probably best to use a hash of the concatenated UIDs in that case.

Finally: using arrays in Firebase Database are often a code-smell. Each user can only be a member of a group once. But an array can contain the same UID multiple times. When you're doing a contains() call on an array, you're often mimicking a set: a collection with unique members. In the Firebase Database, you'd model a set as:

members: {
  uid1: true,
  uid2: true,
  uid3: true
}

With this structure you're guaranteed that each UID can only be present once, you don't need code to ensure that. The true values are just needed because the Firebase Database cannot store a key without a value.

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807