Let’s say you need to use your document’s ID in your application, but you are not storing those IDs in the database.

AngularFire lets you find the IDs and add them to the objects in 2 different ways.

Let’s say you are fetching a regular list of objects from your database using collectionData():

readonly items$ = collectionData(collection(this.firestore, 'items'));

We have 2 ways of getting the ID and adding it to the resulting object, first, we can use the idField parameter:

readonly items$ = collectionData(collection(this.firestore, 'items'), { idField: 'id'});

This is the fastest way and you let angular fire do all the work for you, you tell the collectionData() observable to fetch the ID, and store it in the resulting object with a key of id.

That should work for most people.

The other way is if you need a little more control over the resulting object, like maybe computing a prperty or modifying something before rendering to the user.

Instead of collectionData() you’ll use collectionChanges() which will stream the changes in a given collection of documents, and let you access the payload and modify it as you wish.

For example:

readonly items$ = collectionChanges(
  collection(this.firestore, 'items')
).pipe(
  map((items) =>
    items.map((item) => {
      const data = item.doc.data();
      const id = `idprefix-${item.doc.id}`;
      return { id, ...data };
    })
  )
);

In this example we’re adding a prefix to the item’s ID before we render the object to our user.

You can find the code for the full example on github

And that’s it, it is always better for me to add the ID as a document property, but if you didn’t or couldn’t for some reason, now you have a way to do it.