如何在Angular组件与服务中处理Firebase9的onSnapshot且无需改动组件代码
解决方案
你当前代码不生效的原因是onSnapshot原生为回调模式,直接调用返回的是监听取消函数,而非数据流,因此组件侧无法拿到返回数据。
要实现完全不改动现有组件代码,只调整Service层逻辑,可通过RxJS封装onSnapshot为Observable对象,完美兼容原有组件的subscribe调用逻辑。
方案1:手动封装Observable(灵活可控)
第一步:Service层导入依赖
import { Observable } from 'rxjs'; import { Firestore, doc, onSnapshot } from '@angular/fire/firestore';
第二步:构造函数注入Firestore实例,改造Service方法
constructor(private firestore: Firestore) {} getUserEventSummary(userId: string): Observable<any> { // 封装为Observable返回,和旧版本返回值类型完全一致 return new Observable((subscriber) => { const docRef = doc(this.firestore, `user/${userId}/event_summary/current`); // 调用onSnapshot监听 const unsubscribe = onSnapshot(docRef, (snapshot) => { // 推送数据到订阅流 subscriber.next(snapshot.data()); }, (error) => { // 推送错误信息 subscriber.error(error); } ); // 组件取消订阅时自动销毁监听,防止内存泄漏 return unsubscribe; }); }
组件侧无需任何改动
原有调用逻辑完全可用,不用修改一行代码:
this.service.getUserEventSummary(this.userId).subscribe((res: any) => { this.values = res; })
方案2:使用@angular/fire官方封装API(更简洁)
@angular/fire v7已经内置了兼容v9 modular API的Observable封装方法,无需手动包一层,代码更简洁:
Service改造示例
import { doc, docData } from '@angular/fire/firestore'; getUserEventSummary(userId: string): Observable<any> { const docRef = doc(this.firestore, `user/${userId}/event_summary/current`); // 直接返回docData生成的Observable,和旧版本snapshotChanges行为一致 return docData(docRef); }
注意事项
- 不要使用全局初始化的db实例,统一用Angular依赖注入的Firestore实例,适配Angular的运行环境
- 两种方案均完全兼容原有组件的调用逻辑,不需要修改任何组件代码,可快速全量替换Service层的旧方法
- 监听的自动销毁逻辑和旧版本
snapshotChanges完全一致,不会产生额外的内存泄漏风险
内容的提问来源于stack exchange,提问作者cakePHP
相关产品推荐
相关产品推荐

