javascript - Firestore 查询未获取最新数据
问题描述
我在 Angular 中做了一个路由保护,在允许访问该路由之前检查 firestore 中的某个值。
一旦 HTTP 云功能完成,该组件就会被路由到。此云函数在名为 的 firestore 文档中创建一个对象agreement
,然后路由监听该对象中的状态,以决定是否允许访问。但我们遇到的问题是,可能有 9/10 次,守卫似乎认为该agreement
对象在文档中不存在,因此引发错误。(虽然我可以在 Firestore 中看到协议对象!)。
我已经记录了流程,它正确地记录在订阅中,然后在警卫中,所以我知道 HTTP 函数在尝试路由和调用警卫类之前已经完成。
这是守门员:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.tenancyOffer$ = this._tenancyOffer.getTenancyOfferById(route.params.offerId).get({source: 'server'})).valueChanges();
return this.tenancyOffer$.pipe(
map((tenancyOffer) => {
if (tenancyOffer.status === 'incomplete'
&& tenancyOffer.agreement.status === 'incomplete') {
return true;
} else {
this._router.navigate(['/' + Landlord.base, Landlord.manage.base, Landlord.manage.applications.base, route.params.propId, Landlord.manage.applications.summary, route.params.offerId]);
}
})
);
}
GetTenancyOfferById:
this.tenancyOfferCollection = afs.collection<any>('tenancy_offers');
getTenancyOfferById(id: string) {
return this.tenancyOfferCollection.doc(id);
}
错误来自这部分:tenancyOffer.agreement.status === 'incomplete'
,说TypeError: Cannot read property 'status' of undefined.
我正在调用的 HTTP 函数在这里,在订阅中路由到该组件:
landlordAcceptReferences() {
this.hasAcceptedRefs = true;
this.processingAcceptRefs = true;
this._references.landlordAcceptReferences(this.offerId).pipe(
finalize(() => {
this.processingAcceptRefs = false;
})
).subscribe(e => {
console.log({e});
this.dref.close();
this._toastr.success(`You have accepted tenant references`);
this._router.navigate(['../../', Landlord.manage.applications.agreement.base, this.offerId], {relativeTo: this._activatedRoute});
}, () => this.hasAcceptedRefs = false);
}
我将云函数的响应作为整个 firestore 文档,并且其中包含已记录的协议对象console.log({e});
。然后我在警卫中记录(之后)文档的值,它不存在,即使这是我再次调用 firestore 的地方?
有没有人知道为什么getTenancyOfferById(route.params.offerId)
守卫中的功能没有从firestore返回此文档的最新版本,即使云功能需要在订阅中路由之前结束?
解决方案
I guess this.tenancyOfferCollection = afs.collection<any>('tenancy_offers');
is defined somewhere in your service. If this is true, the collection will be loaded as soon as your application is loaded.
I recommend to store tenancy_offers
values in your service and read it from your guard.
Service:
export class YourService {
private tenancyOfferMap: Map<string, any> = new Map();
constructor(
private afs: AngularFirestore,
) {
afs.collection<any>('tenancy_offers').snapshotChanges()
.subscribe( actions => {
actions.map( action => {
this.tenancyOfferMap.set(action.payload.doc.id, action.payload.doc.data());
});
});
}
getTenancyOfferById(id: string) {
return this.tenancyOfferMap.get(id);
}
}
Guard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
const tenancyOffer = this.yourService.getTenancyOfferById(route.params.offerId);
if (tenancyOffer.status === 'incomplete'
&& tenancyOffer.agreement.status === 'incomplete') {
return true;
} else {
return this._router.navigate(['/' + Landlord.base, Landlord.manage.base, Landlord.manage.applications.base, route.params.propId, Landlord.manage.applications.summary, route.params.offerId]);
}
}
推荐阅读
- qt - 'operator==' 不匹配(操作数类型为 QSerialPortInfo 和 const QSerialPortInfo)
- ios - 如何在自定义 CollectionView 中使用 UIScrollViewDelegate?
- node.js - 用于节点 js 应用程序的 aws cloudwatch 中的 API 日志
- angular - 从其他组件使用时如何在角度模板中替换注入的服务
- httpd.conf - 我的服务器在 /var/log/httpd 上不断生成以下错误。任何 apache 专家都可以在这方面帮助我吗?
- ios - iOS 13:空间分组分隔符已更改
- here-api - 波兰地图和路由引擎缺少 A1 高速公路
- node.js - 在目录上使用 fs.watch 似乎不会注意到添加的文件
- asp.net-core - Web api中soap请求的监听器服务
- python - 如何在swift中使用python方法>