繁体   English   中英

如何使用 AngularFire 观察 Firestore 文档? `onSnapshot() 不工作?

[英]How to observe a Firestore document with AngularFire? `onSnapshot() not working?

使用 Angular 14 和 AngularFire 7.4.1,我为 Firestore 集合做了一个观察者。 它工作得很好:

interface Scientist {
  name?: string | null,
  born?: number | null,
  accomplishment?: string | null
};

scientist$: Observable<Scientist[]>;

constructor(public firestore: Firestore) {
    this.scientist$ = collectionData(collection(firestore, 'scientists'));
}

该集合显示在 HTML 视图中。

我在Firestore 文档中看到也可以观察单个文档。 我是 Charles Babbage 的忠实粉丝,所以我想看看这份文件:

interface Scientist {
  name?: string | null,
  born?: number | null,
  accomplishment?: string | null
};

scientist$: Observable<Scientist[]>;
charle$: Observable<Scientist>;

constructor(public firestore: Firestore) {
  this.scientist$ = collectionData(collection(firestore, 'scientists')); // works
  this.charle$ = onSnapshot(doc(firestore, 'scientists', 'Charles Babbage')); // doesn't work
}

这会引发错误:

Type 'Unsubscribe' is not assignable to type 'Observable<Scientist>'.

哦,是的,Firestore 会返回包含在文档中的数据。 让我们将数据类型更改为any

charle$: Observable<any>;

这会引发同样的错误。 Angular 的Observable和 Firestore 的onSnapshot之间似乎有些不兼容的地方。 是否有 AngularFire 单文档观察者,例如documentData(doc(firestore, 'scientists', 'Charles Babbage')

我有第二个相关的问题。 如何分离收集侦听器?

onSnapshot()返回一个 function ,可以调用它来分离监听器。 它还需要一个 function 作为第二个参数,每次收到更新时都会触发。 尝试重构代码,如下所示:

const unsub = onSnapshot(doc(firestore, 'scientists', 'Charles Babbage'), (snapshot) => {
  console.log("> Updated received", doc.data())
  // TODO: Update data state
});

然后,您可以从 function 本身更新 state。 只需调用unsub(); 并且听者将被分离。

这是基于 Dharmaraj 答案的代码。

import { Firestore, doc, collectionData, collection, onSnapshot } from '@angular/fire/firestore';

interface Scientist {
  name?: string | null,
  born?: number | null,
  accomplishment?: string | null
};

export class AppComponent {
  scientist$: Observable<Scientist[]>;
  charle$: Scientist  = {
    name: null,
    born: null,
    accomplishment: null
  };
  unsubCharle$: any;

  constructor(public firestore: Firestore) {
    this.scientist$ = collectionData(collection(firestore, 'scientists')); // collection listener
    this.unsubCharle$ = onSnapshot(doc(firestore, 'scientists', 'Charles Babbage'), (snapshot: any) => { // document listener
        this.charle$.name = snapshot.data().name;
        this.charle$.born = snapshot.data().born;
        this.charle$.accomplishment = snapshot.data().accomplishment;
    });
  }

  async detachListener() {
    console.log("Detaching listener.");
    this.unsubCharle$();
  }
}
<h3>Observe (collection)</h3>
<ul>
    <li *ngFor="let scientist of scientist$ | async">
        {{scientist.name}}, born {{scientist.born}}: {{scientist.accomplishment}}
    </li>
</ul>

<h3>Observe (single document, 'Charles Babbage')</h3>

<div *ngIf="charle$.name">{{ charle$.name }}, born {{ charle$.born }}: {{ charle$.accomplishment}}</div>

<form (ngSubmit)="detachListener()">
    <button type="submit" value="detachListener">Detach Listener</button>
</form>

这会产生两个观察者,一个集合监听器和一个文档监听器。 可以分离文档侦听器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM