Выполнение запроса группы сбора, чтобы увидеть, является ли поле в моей подколлекции Firebase истинным или ложным - PullRequest
0 голосов
/ 20 января 2020

Я создаю метод входа, который пытается проверить, согласился ли мой текущий пользователь с моими условиями соглашения после проверки своего адреса электронной почты. Моя функция выглядит следующим образом:

SignIn(email, password) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
        .then(cred => {
            this.ngZone.run(() => {
                // Gets current signed in user.
                this.afAuth.authState.subscribe(user => {
                    // Queries Details subcollection.
            this.db.collection('users').doc(user.uid).collection('Details')
                        .get().toPromise().then(
                            doc => {
                                if (user.termsOfAgreement == false) {
                                    this.router.navigate(['terms']);
                                } else {
                                    this.router.navigate(['dashboard']);
                                }
                            })
                })
            });
        }).catch((error) => {
            window.alert(error.message)
        })
}

Я знаю, что я получаю пользовательский объект firebase и что он не содержит мои конкретные поля имен подмножества c (т.е. user.termsOfAgreement). Но как мне получить к ним доступ? Я пытаюсь проверить, является ли мое поле TermsOfAgreement истинным или ложным.

Состояние моей коллекции пользователей Firestore при регистрации

User (Collection)
- lastLogin: timestamp
- name: string
- userId: string

Details (subcollection)
- termsOfAgreement: false 

1 Ответ

1 голос
/ 20 января 2020

Первое замечание: this.db.collection('users').doc(user.uid).collection('Details') - это , а не запрос группы коллекций, но операция чтения для одной коллекции.

Похоже, вы хотите проверить, является ли коллекция Details под пользовательским документом содержится документ с termsOfAgreement, равным true. Проще всего проверить это с помощью:

firebase.firestore()
        .collection('users').doc(user.uid)
        .collection('Details').where('termsOfAgreement', '==', true).limit(1)
        .get().then((querySnapshot) => {
            if (querySnapshot.empty == false) {
                this.router.navigate(['terms']);
            } else {
                this.router.navigate(['dashboard']);
            }
        })

Приведенный выше код использует обычный JavaScript SDK, поскольку для этой операции нет необходимости использовать AngularFire. Но кроме этого, он будет работать одинаково в любом из них: вы запускаете запрос к коллекции и затем проверяете, есть ли какие-либо результаты.

В дополнение к исправлению вашего кода это также оптимизирует его двумя способами:

  1. Запрос отправляется на сервер, поэтому вы передаете только те данные, которые соответствуют условию.
  2. Передается не более одного документа, поскольку вас заботит только результат существует.

Я не уверен, почему вы храните termsOfAgreement во вложенной коллекции.

Если вы проверяете наличие любого поддокумента, где termsOfAgreement имеет значение true, вы можете рассмотреть возможность добавления поля termsOfAgreement в сам пользовательский документ, так что вам не нужно выполнить запрос по вложенной коллекции.

Вы установили бы для этого userDoc.termsOfAgreement значение true, как только пользователь примет какие-либо термины во вложенной коллекции, и тогда больше не придется запрашивать вложенную коллекцию (упрощение кода чтения и сокращение количества операций чтения).

...