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?
4 Answers
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.

- 7,722
- 3
- 24
- 25
-
Is there any way to order keys before select? I tried db.collection(...).orderBy(...).select().get(), but it doesn't seem to be working. Any help would be much appreciated! – elliezen Nov 08 '17 at 12:43
-
This likely is better asked as a new question with what you tried, the results you got, and the results you expected. That said, it should work so long as the fields you want to orderBy are also in the fields you select. – Gil Gilbert Nov 14 '17 at 17:15
-
It is possible that you need and index on the orderBy field before the query can be executed. In the web SDK you get nice error reporting this. Depending on how errors are being handled, it may not be coming through in Admin. – dpsthree Jun 04 '18 at 21:13
-
@GilGilbert would this REST API call count as a single query or would each document ID returned count towards the read quotas? – Luiz Nov 20 '19 at 10:13
-
8Each document you read counts, even if all you read is the document name. – Gil Gilbert Dec 05 '19 at 19:14
-
@GilGilbert I'am not sure about the REST API, but the Admin SDK version should cost only one read per query. This is mentioned in the [pricing](https://firebase.google.com/docs/firestore/pricing#other-queries). – Krisztián Velez Jan 29 '20 at 13:18
-
4@KrisztiánVelez: you're misinterpreting the documentation there. Getting document IDs is a counts as document reads. – Frank van Puffelen Sep 24 '20 at 15:40
-
@FrankvanPuffelen The [pricing](https://firebase.google.com/docs/firestore/pricing#other-queries) documentation seems to indicate that for that query in particular, it only counts as one document read for the whole query, but in all other cases it is one read per document. Is that wrong? – Developer Extraordinare May 07 '22 at 15:02
-
It's phrased a bit confusingly, but what it says is that there's one **additional** document read charge for each read request. – Frank van Puffelen May 08 '22 at 03:01
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)

- 25,773
- 31
- 101
- 122
-
1You could use this to create an endpoint in your functions that your application can call and return a list of all your document ids. – holmberd Feb 06 '21 at 16:56
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)

- 191
- 1
- 8
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]);

- 547
- 8
- 17