Mount Vesubio
Mount Vesubio

Reputation: 85

Firestore query of a collection of documents in which some field does not exist does not work

I have a collection of documents in a Firestore database. All the documents have a field named "debtorEmail", but only some of them have also a field named "creditorEmail". I want to read all the documents in which "creditorEmail" is absent. According to Firestore documentation:

const notCapitalQuery = query(citiesRef, where("capital", "!=", false));

This query does not return city documents where the capital field does not exist. Not-equal (!=) and not-in queries exclude documents where the given field does not exist.

My code is as follows:

const docCollection = collection(db, "requests");
const dataSection = document.getElementById("data-section");
const qRequests = query(docCollection, where("creditorEmail", "!=", false));

but this query delivers precisely those documents in which creditorEmail exists. If I change "false" by "true" the query delivers the same results. It is as if the "!=" condition does not work. Does anybody have any idea of what is wrong?

Upvotes: 1

Views: 2401

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599716

Firestore queries are always based on what information exists about a document in the index using in that query, and if the document doesn't have a field it won't be included in an index on that field.

So what you're seeing is the expected behavior.

Consider giving field a default value, such as an empty string for string fields. That way the document will be present in indexes on/including that field.

Also see:


Update: to test your case, I created a collection 69963042 with three documents:

  • fDmsBjxCdg3xygzjxZo0 with no data in it whatsoever.
  • lxRXLFHoG2NPtC1brv2D with a capital field set to false.
  • wnXLanoHLacRoblnJ7wo with a capital field set to true.

I then ran three queries:

const q = query(
  collection(db, "69963042"),
  where("capital", "!=", false)
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  console.log(`${doc.id}: capital=${doc.get("capital")}`)
})

This logs:

"wnXLanoHLacRoblnJ7wo: capital=true"

Changing the condition to where("capital", "!=", true), leads to logging of:

"lxRXLFHoG2NPtC1brv2D: capital=false"

And finally changing the condition to where("capital", "==", false), leads to logging:

"lxRXLFHoG2NPtC1brv2D: capital=false"

None of the queries returns the document without the capital field, which is working as expected.

For the code, and config for my database in case you want to test yourself, see https://jsbin.com/hudayez/edit?html,console

Upvotes: 1

Related Questions