sisi mendel
sisi mendel

Reputation: 799

Firestore to query by an array's field value

I'm trying to run a simple query, where I search for a document that contains a value inside an object array.

For instance, look at my database structure:

firestore db

I want to run a query similar to this:

db.collection('identites').where("partyMembers", "array-contains", {name: "John Travolta"})

What is the correct way to achieve this, is it even possible with Firestore?

Thanks.

Upvotes: 47

Views: 16928

Answers (4)

Till - gotohuman.com
Till - gotohuman.com

Reputation: 6085

If you control the doc structure and your queried term is unique and doesn't contain special characters, you could turn your array into a map:

partyMembers {
  "7LNKFB9ql": "John Travolta": 
}

and query with e.g. where('partyMembers.7LNKFB9ql', '!=', "")

Lots of ifs, but if dealing with unique user ids, could be an option. In the OPs example of querying by name ("John Travolta") and not id, this might be less feasible, but maybe for someone else.

Upvotes: 0

Renaud Tarnec
Renaud Tarnec

Reputation: 83181

As Frank has explained in his answer it is not possible, with array-contains, to query for a specific property of an object stored in an array.

However, there is a possible workaround: it is actually possible to query for the entire object, as follows, in your case:

db.collection('identites')
  .where(
    "partyMembers",
    "array-contains",
    {id: "7LNK....", name: "John Travolta"}
  )

Maybe this approach will suit your needs (or maybe not....).

Upvotes: 50

saud00
saud00

Reputation: 553

If you want to extract name: "John Travolta" from "partyMembers" array in a document. you can achieve this by some similar approach in which you can loop through all arrays in a document to find this name.

const [names, setNames] = React.useState([])

const readAllNames = async() => {
const snapshot = await firebase.firestore().collection('identites').doc(documentID).get()
      const filterData = snapshot.data().question.map(val => val.name === "John Travolta" ? val : null)
      setNames( filterData.filter(e=>e) );
}
This technique is used in perticular Document as we are giving .doc(documentID) This way you can get all the arrays having name: "John Travolta" in names constant.

Upvotes: -1

Frank van Puffelen
Frank van Puffelen

Reputation: 599946

The array-contains operations checks if an array, contains a specific (complete) value. It can't check if an array of objects, contains an item with a specific value for a property.

The only way to do your query, is to add an additional field to your document with just the value you want to query existence on. So for example: partyMemberNames: ["John Travolta", "Olivia Newton"].

Upvotes: 32

Related Questions