如何使用 AngularFirestore 查询单个文档?

How to query for a single doc with AngularFirestore?

如何构建仅限于单个文档的 Observable?

这会在查询任意数量的文档时构建一个 Observable:

foo.component.ts

import { AngularFirestore } from '@angular/fire/firestore';
import { Observable } from 'rxjs';

...

export class FooComponent implements OnInit {

...

    docs: Observable<any[]>;

    constructor(private db: AngularFirestore) {
        this.docs = db.collection('myCollection', ref => ref.where('name', '==', 'foobar')).valueChanges();

}

foo.component.html

<div *ngFor="let doc of docs | async">
    {{ doc.name }}, {{ doc.address }}
</div>

当我知道只有 1 个文档会被退回时,我该如何执行此操作?我只是不会提前知道文档 ID。

类似于上面的代码,只是使用 doc: Observable<any>; 而不是 docs: Observable<any[]>;,所以我不必对结果使用 *ngFor 循环?

我试过了

this.doc = db.collection('myCollection', ref => ref.where('name', '==', 'foobar').limit(1)).valueChanges();

工作 stackblitz:https://stackblitz.com/edit/angular-v7yff2

https://stackblitz.com/edit/angular-lymeyp的基础上,只需要在组件

中进行如下操作
crazinessToObserveASingleDoc() {
        this.singleDoc = this.db.collection('users', ref => ref.where('email', '==', this.email)).valueChanges().pipe(
          tap(docs => console.log('docs', docs)),
          map(val => val.length > 0 ? val[0] : null)
        )
    }

并在模板中

<div>
    <span class="title">Document with email <span class="italics">{{ email }}</span>:</span>
    <div *ngIf="singleDoc | async as doc">{{ doc.name }}, {{ doc.email }}</div>
</div>

上一个解决方案

不要像一些评论中建议的那样做take(1):它完成了可观察的,然后你将停止监听变化(那为什么要使用实时数据库?)。此外,您仍会收到一系列结果...

如果你不知道文档的id,你需要做的是:

const doc: Observable<any | null> = 
   db.collection('myCollection', ref => ref.where('name', '==', 'foobar'))
     .valueChanges()
     .pipe(map(val => val.length > 0 : val[0] : null));

where map if from rxjs/operators.