我正在创建一种登录方法,该方法试图在验证他们的电子邮件地址后检查当前用户是否已同意我的协议条款。我的功能如下:
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
答案 0 :(得分: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。但是除此之外,这两种方法都一样:您针对集合触发查询,然后检查是否有结果。
除了修正您的代码外,这还通过两种方式对其进行了优化:
我不确定您为什么将termsOfAgreement
存储在子集合中。
如果要检查termsOfAgreement
为真的子文档的存在,则可能要考虑向用户文档本身添加一个termsOfAgreement
字段,这样就不需要在整个子集合中执行查询。
一旦用户接受子集合中的任何术语,就可以将此userDoc.termsOfAgreement
设置为true,然后就不必再查询子集合了(简化了读取代码并减少了读取操作的次数)。