6

In this document of Cloud Foreshore it is mentioned that 'a request for a list of collection IDs, you are billed for one document read.'

Now I am using AngularFire and Ionic3 for my project. My requirement is to fetch just the collection IDs from a collection with a where condition. If I do the following, it will cost me the number of reads = number of docs in the result.

let snap = this.afs.collection('path').ref
        .where('field', "==",'data').get();

snap.forEach(x => {
          list.push(x.id);
        });

I am not able to use method getCollections() which I found in a few places as a solution.

Please let me know if you have a solution.

Tapas Mukherjee
  • 2,088
  • 1
  • 27
  • 66

4 Answers4

7

The Firestore getCollections() method only exists in the server-side SDKs, where it is charged as a single read operation. But as Doug answered, it returns the collection ids/names, not the document ids.

To get the document IDs on the client, you will need to read the entire document. So this will be charged as the number of document you read, and will consume bandwidth for all data in each document.

On the server, you can use the select() method to get a list of only the document IDs. You will still be charged for reading each of the documents, but it will consume less bandwidth.

See:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • That explains everything. There's no way to read document IDs as a single read (no matter client/server side). Thank you Frank! – tomrozb Jun 09 '20 at 12:43
4

It sounds like you are wondering if there is a way to get all the document IDs in a collection without incurring a read for each document. This is currently not possible. When using Firestore client SDKs, your only option is to query the entire collection, which will transfer the entire contents of every document to the client.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 7
    What if it's about memory size? Say you have a big collection of documents which each has several hundred kilobytes. You only want the IDs of the documents, to be able to list / link to them. If all the document contents are loaded, you will have hundreds of megabytes in memory without needing them. – Jonas Sourlier Mar 13 '20 at 22:18
  • We are currently facing this issue and for us it is more about bandwidth. The cold boot of the cloud function is too slow to do it in the back-end. – anonymous-dev Jun 21 '21 at 12:52
4

NOTE: You'll be billed on one read per document retrieved. There is no way of being billed only once for this operation.

As people have mentioned in other answer, this is not possible on the client firebase SDK. But this is possible using the firebase-admin from your server code.

This is how you can do it:

admin.initializeApp(config);

const querySnapshot = await admin.firestore().collection("YOUR_COLLECTION").select().get();
for (const docSnapshot of querySnapshot.docs) {
  console.log(docSnapshot.id);       // THIS WILL PRINT THE DOC ID
  console.log(docSnapshot.data());   // THIS WILL PRINT EMPTY OBJECT {}
}

You can see that docSnapshot.data() prints {} because no document data was retrieved, other than the document reference inside docSnapshot.

This is useful to get a huge document list of ID's without having to download the huge document data that would come along with it, if you were to use something like: admin.firestore().collection("YOUR_COLLECTION").get()

https://googleapis.dev/nodejs/firestore/latest/CollectionReference.html#select

You can also pass where() clauses before the select() so you can filter the collection with it.

enter image description here

cbdeveloper
  • 27,898
  • 37
  • 155
  • 336
1

Even i faced similar situation where i wanted the count of total documents in a collection, but firebase neither gives u document count or just document ids, when you query collection it return the list of document with entire content of documents.

ked
  • 2,426
  • 21
  • 24