【问题标题】:Running a collection group query to see if a field in my firebase subcollection is true or false运行集合组查询以查看我的 firebase 子集合中的字段是 true 还是 false
【发布时间】:2020-01-19 22:16:31
【问题描述】:

我正在创建一种登录方法,该方法试图检查我当前的用户在验证他们的电子邮件地址后是否同意我的协议条款。我的功能如下:

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 用户对象,并且它不包含我的特定子集合字段名称(即 user.termsOfAgreement)。但是我将如何访问这些?我正在尝试检查我的 termsOfAgreement 字段是真还是假。

注册时我的 Firestore 用户集合状态

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

Details (subcollection)
- termsOfAgreement: false 

【问题讨论】:

    标签: javascript firebase google-cloud-firestore angularfire


    【解决方案1】:

    首先注意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 为真的任何子文档是否存在,您可能需要考虑将 termsOfAgreement 字段添加到用户文档本身,这样您就不需要执行查询跨子集合。

    一旦用户接受子集合中的任何术语,您就可以将此 userDoc.termsOfAgreement 设置为 true,然后就不必再查询子集合(简化读取代码并减少读取操作的次数)。

    【讨论】:

    • 嘿弗兰克,非常感谢您的指导。我仍然习惯于从 SQL 过渡到 NoSQL。我会将子集合提升到主文档级别。在你解释之后,这更有意义。
    猜你喜欢
    • 2019-09-02
    • 1970-01-01
    • 2021-08-04
    • 2019-03-27
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 2023-03-31
    • 2021-10-26
    相关资源
    最近更新 更多