背景:我试图从一个集合中检索一个文件而不是它的ID。我基本上是想创建一个登录系统。
我尝试了这个解决方案:Firestore : Retrieve a single document
使用flat-map来限制(1)来做但它似乎没有给出任何东西,这就是我的代码现在的样子:
this.user = this.afs.collection('users/', ref => ref.where('username',
'==', this.username).limit(1)).valueChanges().flatMap(result => result);
console.log(this.user.username);
输出是未定义的,但如果我只打印用户,我会得到可观察的
答案 0 :(得分:1)
您应该将this.user
设置为Observable参考,然后按以下方式订阅:
this.user = this.afs.collection('users', (ref) => ref.where('username', '==', this.username).limit(1)).valueChanges();
// I removed the slash after 'users' as it isn't necessary
然后像这样订阅Observable:
this.user.subscribe((user) => {
console.log(user);
});
哪个应该只给你一个结果。控制台记录Observable不会显示数据,而是记录Observable对象。
请注意,您应该拥有与该用户名相关的userId并提取文档,因为它比获取与字段匹配的集合并将其限制为1更安全,更明确。如果这是认证问题,您应该使用Firebase Auth并使用任何形式的身份验证作为用户名,Firebase Auth将处理没有重复登录。如果需要使用用户名而不是电子邮件,您可以请求,但您的方法应该只返回请求的长度,如下所示:
this.user = this.afs.collection('users',
(ref) => {
return ref.where('username', '==', this.username).limit(1)
})
.snapshotChanges()
.map((users) => {
return users.length
});
这样您就不会在请求中返回hte用户对象,而是返回一个数字,如果它大于零,则用户已经拥有该用户名。
由于您使用的是valueChanges()
而不是snapshotChanges()
,因此在将数据显示在DOM上之前,您不需要操作数据,因此您无需订阅数据,而是订阅在标记中使用ASYNC管道的Observable。这是我前几天解答的一个问题,它解释了您的问题,并在您的标记中使用了ASYNC管道:Angular Observable Array Object Conversion