Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore query where map contains string

Data structure:

houses (collection)
  name (string)
  users (map)
    90c234jc23 (map)
      percentage: 100% (string/number)

Rules:

allow read: request.auth.uid in resource.data.users;

The problem is when I try to query houses which user owns:

FirebaseFirestore.getInstance().collection(House.COLLECTION)
//                .whereArrayContains(House.USERS_FIELD, currentUser.getUid()) // does not work
                .whereEqualTo("users." + currentUser.getUid(), currentUser.getUid()) // does not work either
                .get()

No result are returned.

like image 904
Jaky Avatar asked Dec 05 '22 10:12

Jaky


1 Answers

You cannot perform this type of query in firestore as there is no 'map-contains-key' operator. However, there are very simple workarounds for implementing this by making slight adjustments to your datastructure.

Specific Solution

Requirement: For this solution to work, each map value has to be uniquely identifyable in a firestore query, meaning it cannot be a map or an array.

If your case meets the listed requirements, you can go with @Dennis Alund's solution which suggests the following data structure:

{
  name: "The Residence",
  users: {
    uid1: 80,
    uid2: 20
  }
}

General Solution

If your map values are maps or arrays, you need to add a property to each value which will be constant across all created values of this type. Here is an example:

{
  name: "The Residence",
  users: {
    uid1: {
      exists: true,
      percentage: 80,
      ...
    },
    uid2:  {
      exists: true,
      percentage: 20,
      ...
    },
  }
}

Now you can simply use the query:

_firestore.collection('houses').whereEqualTo('users.<uid>.exists', true)

Edit:

As @Johnny Oshika correctly pointed out, you can also use orderBy() to filter by field-name.

like image 57
Lucas Aschenbach Avatar answered Dec 20 '22 08:12

Lucas Aschenbach