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

时间:2019-11-23 07:09:04

标签: angular typescript firebase angularfire2 angularfire

我如何构建仅限于单个文档的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();

1 个答案:

答案 0 :(得分:1)

有效的堆叠闪电战: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));

如果来自rxjs/operators的位置图。