我想基于Firestore中用户配置文件上的accountId属性限制用户可以访问的数据,每当创建新用户时都会设置accountId。
我正在使用Angular 6,Rxjs,Ngrx和AngularFire2。
我正在努力寻求最佳方法,并考虑了以下问题:
这是我的首选,因为我可以将其设置在一个位置,并且始终知道用户只能访问适当的数据
写入Firestore数据库的每个文档始终将currentUsers accountId写入文档中的属性
当我尝试首选解决方案时,我一直未获得accountId,但是,当我在Firestore数据库中签入时,用户具有accountId,而在我的ngrx中签入时,用户具有accountId。
这似乎是一个计时问题,但不确定如何在登录时始终确保在用户accountId可用之前对数据库没有查询。
我的console.log显示在运行firestore构造函数中的订阅之前,firestore查询正在运行
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import { fromPromise } from 'rxjs/observable/fromPromise';
import { of } from 'rxjs/observable/of';
import { expand, takeWhile, mergeMap, take, catchError } from 'rxjs/operators';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/take';
import 'rxjs/add/operator/do';
import * as firebase from 'firebase/app';
import { AuthService } from '@core/services/auth.service';
import { User } from '../../shared/models';
import { from, throwError } from 'rxjs';
type CollectionPredicate<T> = string | AngularFirestoreCollection<T>;
type DocPredicate<T> = string | AngularFirestoreDocument<T>;
@Injectable()
export class FirestoreService {
colRef: any;
user: User;
currentUser: User;
currentUser$: Observable<any>;
constructor(
public afs: AngularFirestore,
private authService: AuthService,
) {
this.authService.user.subscribe(res => {
this.user = res;
if (this.user) {
this.currentUser$ = this.afs
.collection('users', ref => ref.where('id', '==', this.user.id))
.valueChanges();
}
this.currentUser$.subscribe(user => {
this.currentUser = user;
console.log('Constructor:', this.currentUser);
});
});
}
/// **************
/// Get a Reference
/// **************
col<T>(ref: CollectionPredicate<T>, queryFn?): AngularFirestoreCollection<T> {
return typeof ref === 'string' ? this.afs.collection<T>(ref, queryFn) : ref;
}
/// **************
/// Get Data - NGRX Effects makes a call to this method
/// **************
col$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<T[]> {
return this.col(ref, queryFn)
.snapshotChanges()
.map(docs => {
return docs.map(a => a.payload.doc.data()) as T[];
});
}
/// with Ids
colWithIds$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<any[]> {
if (queryFn === undefined) {
if (this.currentUser) {
console.log('Firestore Query:', this.currentUser);
queryFn = reference => reference.where('accountId', '==', this.currentUser.accountId);
}
}
console.log('FireStore Query');
return this.col(ref, queryFn)
.snapshotChanges()
.map(actions => {
return actions.map(a => {
const data: any = a.payload.doc.data();
const id = a.payload.doc.id;
return { id, ...data };
});
});
}
}