Élyse
Élyse

Reputation: 1361

Firestore Getting documents id from collection

I'm trying to retrieve my documents with id but can't figure it out.
Currently I retrieve my documents like this :

const racesCollection: AngularFirestoreCollection<Races> = this.afs.collection('races');
return racesCollection.valueChanges();

I do get my documents list perfectly, however there is no doc id with them.

How can I retrieve it for each document ?

Upvotes: 77

Views: 185826

Answers (11)

Woden
Woden

Reputation: 1386

Here are my implementations with Angular 17 and Firestore modular API.

function getAllDestinations() {
    return defer(() =>
      from(getDocs(query(collection(getFirestore(), 'countries'))))
    );
  }

function fetchDestinations(
    fetchMethod: () => Observable<QuerySnapshot<DocumentData, DocumentData>>
  ): Observable<Destination[]> {
    return fetchMethod().pipe(
      switchMap((documents) => {
        const data = documents.docs.map((doc) => {
          return { ...doc.data(), id: doc.id }; // <-- include the document id
        }) as Destination[];
        // ... other details
      })
    );
  }

// usage
fetchDestinations(() => getAllDestinations()).pipe(
  tap(data: Destination) => {/* deal with data */}
).subscribe()

Upvotes: 0

Daniel Danielecki
Daniel Danielecki

Reputation: 10502

Sadly, in React Native environment, I couldn't find a way to import doc, to get the id. I'm working with https://rnfirebase.io/firestore/usage. It can be the same case for some less common environments relying on Firebase plugin/libraries.

In that case console.log(documentSnapshot.ref); will return you what you can find below.

enter image description here

as you could see, while working with the raw response, it can be accessed via documentSnapshot.ref._documentPath._parts[1]. documentSnapshot is of course part of querySnapshot.

Upvotes: 0

phicon
phicon

Reputation: 3617

For angular6+

    this.shirtCollection = afs.collection<Shirt>('shirts');
    this.shirts = this.shirtCollection.snapshotChanges().pipe(
        map(actions => {
        return actions.map(a => {
            const data = a.payload.doc.data() as Shirt;
            const id = a.payload.doc.id;
            return { id, ...data };
        });
        })
    );

Upvotes: 38

Luis Ruiz Figueroa
Luis Ruiz Figueroa

Reputation: 2577

To obtain the id of the documents in a collection, you must use snapshotChanges()

    this.shirtCollection = afs.collection<Shirt>('shirts');
    // .snapshotChanges() returns a DocumentChangeAction[], which contains
    // a lot of information about "what happened" with each change. If you want to
    // get the data and the id use the map operator.
    this.shirts = this.shirtCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data() as Shirt;
        const id = a.payload.doc.id;
        return { id, ...data };
      });
    });

Documentation https://github.com/angular/angularfire2/blob/7eb3e51022c7381dfc94ffb9e12555065f060639/docs/firestore/collections.md#example

Upvotes: 52

Trilok Singh
Trilok Singh

Reputation: 1353

I have tried this

return this.db.collection('items').snapshotChanges().pipe(
          map(actions => {       
            return actions.map(a => {
              const data = a.payload.doc.data() as Item;
              data.id = a.payload.doc.id;
              data.$key = a.payload.doc.id;
              return data;
            });
          })
        );

Upvotes: 0

Jonathan
Jonathan

Reputation: 4689

For document references, not collections, you need:

// when you know the 'id'

this.afs.doc(`items/${id}`)
  .snapshotChanges().pipe(
    map((doc: any) => {
      const data = doc.payload.data();
      const id = doc.payload.id;
      return { id, ...data };
    });

as .valueChanges({ idField: 'id'}); will not work here. I assume it was not implemented since generally you search for a document by the id...

Upvotes: 3

Hasintha Abeykoon
Hasintha Abeykoon

Reputation: 524

Since you are using angularFire, it doesn't make any sense if you are going back to default firebase methods for your implementation. AngularFire itself has the proper mechanisms implemented. Just have to use it.

valueChanges() method of angularFire provides an overload for getting the ID of each document of the collection by simply adding a object as a parameter to the method.

valueChanges({ idField: 'id' })

Here 'idField' must be same as it is. 'id' can be anything that you want your document IDs to be called.

Then the each document object on the returned array will look like this.

{
  field1 = <field1 value>,
  field2 = <field2 value>,
  ..
  id = 'whatEverTheDocumentIdWas'
}

Then you can easily get the document ID by referencing to the field that you named.

AngularFire 5.2.0

Upvotes: 20

Ivan Tarskich
Ivan Tarskich

Reputation: 1527

For angular 8 and Firebase 6 you can use the option id field

      getAllDocs() {
           const ref = this.db.collection('items');
           return ref.valueChanges({idField: 'customIdName'});
      }

this adds the Id of the document on the object with a specified key (customIdName)

Upvotes: 70

corysimmons
corysimmons

Reputation: 7675

doc.id gets the UID.

Combine with the rest of the data for one object like so:

Object.assign({ uid: doc.id }, doc.data())

Upvotes: 26

Diego Ven&#226;ncio
Diego Ven&#226;ncio

Reputation: 6007

Can get ID before add documents in database:

var idBefore =  this.afs.createId();
console.log(idBefore);

Upvotes: 3

&#201;lyse
&#201;lyse

Reputation: 1361

I've finally found the solution. Victor was close with the doc data.

const racesCollection: AngularFirestoreCollection<Race>;
return racesCollection.snapshotChanges().map(actions => {       
  return actions.map(a => {
    const data = a.payload.doc.data() as Race;
    data.id = a.payload.doc.id;
    return data;
  });
});

ValueChanges() doesn't include metadata, therefor we must use SnapshotChanges() when we require the document id and then map it properly as stated here https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md

Upvotes: 44

Related Questions