首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Firestore查询未获取最新数据

Firestore查询未获取最新数据
EN

Stack Overflow用户
提问于 2020-12-04 17:04:36
回答 2查看 68关注 0票数 0

我在Angular中做了一个路由守卫,在允许访问所述路由之前,它会检查firestore中的某个值。

一旦HTTP云函数完成,该组件就被路由到。这个云函数在一个名为agreement的firestore文档中创建一个对象,然后路由侦听该对象中的状态,以决定是否允许访问。然而,我们遇到的问题是,可能有9/10次,防护人员似乎认为agreement对象不存在于文档中,因此抛出错误。(虽然我可以在firestore中看到协议对象!)。

我已经记录流,它正确地记录了订阅中的日志,然后是guard中的日志,因此在尝试路由和调用guard类之前,我知道HTTP函数正在完成。

这是守卫:

代码语言:javascript
运行
复制
  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:

代码语言:javascript
运行
复制
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函数在这里,在订阅中路由到这个组件:

代码语言:javascript
运行
复制
  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的地方?

有人知道为什么guard中的getTenancyOfferById(route.params.offerId)函数没有从firestore返回此文档的最新版本,即使云函数需要在订阅中路由之前结束吗?

EN

回答 2

Stack Overflow用户

发布于 2020-12-04 18:24:40

我猜this.tenancyOfferCollection = afs.collection<any>('tenancy_offers');是在您的服务中定义的。如果为真,则在加载应用程序后将立即加载该集合。

我建议将tenancy_offers值存储在您的服务中,并从您的守卫那里读取它。

服务:

代码语言:javascript
运行
复制
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);
  }

}

防护:

代码语言:javascript
运行
复制
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]);
    }
  }
票数 1
EN

Stack Overflow用户

发布于 2020-12-04 23:14:56

这可能取决于您的流没有完成的事实。

代码语言:javascript
运行
复制
 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    this.tenancyOffer$ = this._tenancyOffer.getTenancyOfferById(route.params.offerId).get({source: 'server'})).valueChanges()
      .pipe(take(1)); // <-- ensure your stream completes in guards

    return this.tenancyOffer$.pipe(
      map((tenancyOffer) => {
        if (tenancyOffer && 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]);
          return false; // <-- always return something in guards
        }
      })
    );
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65140663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档