如何在Firestore数据库中获取document.id?Angular新手求助
解决Firestore获取文档ID传递路由的问题
嘿,我刚入门Angular和Firebase的时候也踩过这个坑!Firestore返回的文档数据默认是不带id的——因为id是文档本身的属性,不在你存在Firestore里的字段里。所以直接用hero.id肯定拿不到值,下面给你两种简单的解决办法:
方法一:用snapshotChanges()合并ID到数据对象
如果你的代码之前是用valueChanges()获取数据,那换成snapshotChanges()就能拿到包含文档快照的数据流,然后我们可以把ID合并到英雄对象里:
import { Component, OnInit } from '@angular/core'; import { AngularFirestore } from '@angular/fire/compat/firestore'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; // 先定义Hero接口(如果还没的话) export interface Hero { id: string; name: string; // 你的其他英雄字段,比如power、bio等等 } @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] }) export class HeroesComponent implements OnInit { heroes$: Observable<Hero[]>; constructor(private afs: AngularFirestore) { } ngOnInit(): void { this.heroes$ = this.afs.collection('heroes').snapshotChanges().pipe( map(actions => { return actions.map(action => { // 取出文档里的数据 const heroData = action.payload.doc.data() as Omit<Hero, 'id'>; // 取出文档ID const id = action.payload.doc.id; // 合并成带ID的Hero对象 return { id, ...heroData }; }); }) ); } }
然后在模板里就可以直接用hero.id来跳转路由了:
<div *ngFor="let hero of heroes$ | async"> <h3><a [routerLink]="['/hero-detail', hero.id]">{{ hero.name }}</a></h3> </div>
方法二:用valueChanges()的idField参数(更简单)
AngularFire后来加了个更便捷的选项,直接在valueChanges()里指定idField,就能让Firestore自动把ID添加到返回的对象中:
ngOnInit(): void { // 这里指定idField为'id',返回的每个英雄对象就会自带id属性 this.heroes$ = this.afs.collection('heroes').valueChanges({ idField: 'id' }) as Observable<Hero[]>; }
这种方法代码更简洁,适合不需要文档其他元数据(比如创建时间)的场景,直接用hero.id就没问题啦!
最后别忘了,如果你有Hero接口,一定要把id字段加进去,这样TypeScript才不会报错哦~
内容的提问来源于stack exchange,提问作者iSebbeYT
相关产品推荐
相关产品推荐

