ntgCleaner
ntgCleaner

Reputation: 5985

Firestore query document where object key exists

I am writing an app that keeps track of events. I'm using firestore to have a main collection of events which houses each event as a document. Each document has its own details (including a roles object) and their own collection of steps within the event.

The collection object looks like this:

events > [collection]
    eventid1 > [doc]
        steps > [collection]
        location: "Even Center",
        notes: "Some notes here",
        timestamp: 1272153600,
        title: "A great event",
        roles:
            userID1: 0, //numbers to define role type
            userID2: 1,
            userID3: 1,

What I'm trying to do is query any event where roles.userID1 exists. I know firestore does not have sub-collection querying, so this is the closest I have come to solving this.

There are only 3 "roles" (0 = owner, 1 = editor, 2 = viewer). I tried writing three queries and combining the queries using .where("roles." + this.user.uid, "==", 0). This would work (though I had some array issues after the fact) but I don't want to have to make 3 calls per user viewing this.

I saw in a random comment somewhere you can use the query .where("roles." + this.user.uid, "<", ""), but this did not work for me.

Is there a way to write a query that is able to see if a key within an object exists?

Upvotes: 4

Views: 6226

Answers (2)

Johnny Oshika
Johnny Oshika

Reputation: 57552

You can use orderBy to find documents where an object key exists. For example, let's say you have a document that looks like this:

{
  "users": {
    "bob": {},
    "sam": {},
  }
}

You can find all documents that contain users.bob like this:

.orderBy('users.bob')

Upvotes: 10

ntgCleaner
ntgCleaner

Reputation: 5985

As my comment stated above, I was able to answer my own question because I accidentally set myself up for success.

Early on, I decided to give my roles a number value, rather than a string value. 0, 1 and 2. Now seeing that, I was able to realize that I can use the .where clause efficiently just by using < 3.

My query now includes .where("roles." + this.user.uid, "<", 3).

This effectively looks at the sub-object of roles (the whole string would be something like .where("roles.ehHH-scSd-d222-njsl-LLewS, "<", 3). (3 being not a role, so if you have more than 3 roles, bump the number).

Upvotes: 6

Related Questions