elliezen
elliezen

Reputation: 543

How to get a list of document IDs in a collection Cloud Firestore?

I have a collection of documents with generated identifiers. The question is: is it possible to get a list of identifiers without querying all documents data? Is it better to store these keys in a separate collection?

Upvotes: 39

Views: 31095

Answers (4)

Chris Chiasson
Chris Chiasson

Reputation: 816

Here is some JavaScript and a little React code that seems to be working for me with the V1 REST API's runQuery using client SDK bearer tokens in the browser (Chrome). This is patterned off of Gil Gilbert's answer. However, note that parent does not appear in the body by the structured query, and unlike some other answers on Stack Overflow, there is no API key necessary.

  const [token, setToken] = useState("");
  useEffect(() => {
    if (!token) firebase.auth().currentUser.getIdToken(true).then(setToken);
  }, [token]);

  const getCollectionAsync = useCallback(async collection => {
    try {
      if (!token) return [];

      const parent = `projects/${projectId}/databases/(default)/documents`;
      const url = `https://firestore.googleapis.com/v1/${parent}:runQuery`;
      const Authorization = `Bearer ${token}`;
      const headers = {Authorization, "Content-Type": "application/json"};
      const body = {structuredQuery: {from: [{collectionId: collection}],
        select: {fields: [{"fieldPath": "__name__"}]}}};

      const response = await fetch(url,
        {method: "POST", headers, body: JSON.stringify(body)});
      const json = await response?.json?.();
      return json;

    } catch (error) {
      console.error(error);
      return [];
    }
  }, [cache, token]);

Upvotes: 0

Mecit Semerci
Mecit Semerci

Reputation: 191

I had a need to fetch only ids without pulling fields of all documents in Python.

I used google-cloud-firestore 2.6.0 package.

select and field_paths keywords were the very important part of this query. They allowed me to process without downloading all documents.

from google.cloud import firestore_v1

db = firestore_v1.Client()

items = db.collection("your_collection_name").select(field_paths=[]).get()
ids = [item.id for item in items]

print(ids)

Upvotes: 0

tomrozb
tomrozb

Reputation: 26271

On node.js runtime you can get the list of document IDs like this

const documentReferences = await admin.firestore()
        .collection('someCollection')
        .listDocuments()

const documentIds = documentReferences.map(it => it.id)

Upvotes: 22

Gil Gilbert
Gil Gilbert

Reputation: 7870

The answer depends on which API you're trying to use.

For mobile/web SDKs there is no way to do what you're asking for since these clients do not support projections of any kind.

For server SDKs you can do an empty projection, i.e.

db.collection('foo').select()

In this case the server will send you the documents that match, but will omit all fields from the query result.

For the REST API you can do the equivalent with a runQuery that includes a field mask of '__name__', like so:

curl -vsH 'Content-Type: application/json' \
  --data '{
    "parent": "projects/my-project/databases/(default)",
    "structuredQuery":{
      "from": [{"collectionId": "my-collection"}],
      "select": {
        "fields": [{"fieldPath":"__name__"}]
      }
    }
  }' \
  'https://firestore.googleapis.com/v1beta1/projects/my-project/databases/(default)/documents:runQuery'

Substitute my-project and my-collection as appropriate. Note that the "collectionId" in the "from" is only the right most name component. If you want keys in a subcollection the REST API wants the parent document name in the "parent" field.

Upvotes: 34

Related Questions