Angular: 6.1.0
Firebase: 5.5.4
AngularFire: 5.1.1
Steps to set up and reproduce
book: any = {};
bookList: any[] = [];
constructor (private db: AngularFirestore) {}
ngOnInit {
this.book = this.db.doc('path/to/books/shrek').valueChanges();
this.bookList = this.db.collection('path/to/books').valueChanges();
// Observing Changes
this.book.subscribe(p => console.log('Selected book', p));
this.bookList.subscribe(p => console.log('Book list', p));
}
```HTML
ID: {{book.$key}}
```HTML
<a routerLink="/story/{{item.$key}}" *ngFor="let item of bookList | async">{{item.title}}</a>
Sample data
"books": {
"shrek": {
"title": "Shrek the Ogre"
},
"tangled": {
"title": "The magic of Rapunzel"
}
}
_$key_ or _id_ is missing in query result.
Result in the JavaScript console


Oh, I think I've gotten it.
Use _snapshotChanges()_ instead of _valueChanges()_
The map the observable to an array with the _$key_ or _id_
...
public getItemList(path: string, query?: QueryFn) { // Get list of items in a path
return this.db.collection(path, query).snapshotChanges().pipe(map((mutation: any[]) => mutation.map(p => {
return { ...p.payload.doc.data(), '$key': [p.payload.doc.id][0] };
// OR
return { ...p.payload.doc.data(), 'id': [p.payload.doc.id][0] };
})));
}
...
This seems a little ridiculous for such a simple and absolutely essential feature or am I missing something? One would absolutely expect to have a key exposed on an object or else there's little you can do with it.
This doesn't seem to work anymore as doc is no longer available:
Property 'doc' does not exist on type 'DatabaseSnapshot
'
Most helpful comment
This seems a little ridiculous for such a simple and absolutely essential feature or am I missing something? One would absolutely expect to have a key exposed on an object or else there's little you can do with it.