[英]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.