Запрос Firestore на основе текущего логина - PullRequest
0 голосов
/ 16 сентября 2018

Я хочу ограничить данные, к которым пользователь может получить доступ, на основе свойства accountId профиля пользователя в Firestore, accountId устанавливается при создании нового пользователя.

Я использую Angular 6, Rxjs, Ngrxи AngularFire2.

Я изо всех сил пытаюсь найти лучший способ сделать это и рассмотрел следующее:

  1. Установить AccountId в локальном хранилище.Это работает, но не очень безопасно
  2. Установите фильтр в моей службе пожарной охраны.

Это мой предпочтительный вариант, так как я могу установить его в одном месте и всегда знать, что пользователь может получить доступ только к соответствующим данным

Каждый документ, записанный в базу данных firestore, всегда имеет currentUsersaccountId, записанный в качестве свойства в документе

Когда я пытаюсь выбрать предпочтительное решение, я получаю accountId не определено, однако, когда я захожу в свою базу данных firestore, у пользователя есть accountId, а когда я захожу в свой ngrx, пользователь имеетaccountId.

Похоже, что это проблема синхронизации, но вы не знаете, как всегда гарантировать, что при входе в систему не будет запросов к базе данных, пока не будет доступен идентификатор учетной записи пользователя.

Показ моей консоли.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 };
                });
            });
    }

}

...