简体   繁体   English

FireStore 查询单个文档

[英]FireStore Querying for a single document

background: I am trying to retrieve one document from a collection with a value rather than it's ID.背景:我试图从具有值而不是 ID 的集合中检索一个文档。 I'm basically trying to make a login system.我基本上是在尝试制作一个登录系统。

I tried this solution: Firestore : Retrieve a single document我试过这个解决方案: Firestore : Retrieve a single document

using flat-map to and limit(1) to do it but it does not seem to give anything, this is what my code looks like right now:使用 flat-map to 和 limit(1) 来做它,但它似乎没有给出任何东西,这就是我的代码现在的样子:

this.user = this.afs.collection('users/', ref => ref.where('username',
      '==', this.username).limit(1)).valueChanges().flatMap(result => result);
    console.log(this.user.username);

the output is undefined, though if I do just print the user I do get the observable输出未定义,但如果我只是打印用户,我会得到可观察的

You should be setting this.user to the Observable reference and then subscribing to it like so:您应该将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

Then subscribe to that Observable like so:然后像这样订阅那个 Observable:

this.user.subscribe((user) => {
 console.log(user);
});

Which should give you back only one result.这应该只给你一个结果。 Console Logging the Observable will not display the data but log the Observable object.控制台记录 Observable 不会显示数据,但会记录 Observable 对象。

Keep note that you should have the userId that correlates with that username and fetching a document instead as it will be more secure and more definite than fetching a collection that matches a field and limiting it to 1. If this is matter of authentication, you should be using Firebase Auth and using whatever form of authentication as the username and Firebase Auth will handle not having duplicate logins.请注意,您应该拥有与该用户名相关的 userId 并获取文档,因为它比获取与字段匹配的集合并将其限制为 1 更安全、更明确。如果这是身份验证问题,您应该使用 Firebase Auth 并使用任何形式的身份验证作为用户名,Firebase Auth 将处理没有重复登录的情况。 If desired to use usernames instead of an email, you can request but your method should just return the length of your request like so:如果希望使用用户名而不是电子邮件,您可以请求,但您的方法应该只返回请求的长度,如下所示:

 this.user = this.afs.collection('users', 
  (ref) => {
    return ref.where('username', '==', this.username).limit(1)
  })
  .snapshotChanges()
  .map((users) => {
    return users.length
  });

This way you are not returning the user object in your request but instead returning a number and if it is greater than zero, a user already has that username.这样您就不会在请求中返回用户对象,而是返回一个数字,如果它大于零,则用户已经拥有该用户名。

Since you are using valueChanges() instead of snapshotChanges() it seems as you do not need to manipulate the data before displaying it on the DOM so you do not need to subscribe to the data but instead subscribing to the Observable using the ASYNC pipe in your markup.由于您使用的是valueChanges()而不是snapshotChanges()因此您似乎不需要在将数据显示在 DOM 上之前对其进行操作,因此您不需要订阅数据,而是使用 ASYNC 管道订阅 Observable你的标记。 This is a question I asnwered the other day which explains your issue here as well as using the ASYNC pipe in your markup: Angular Observable Array Object Conversion这是我前几天回答的一个问题,它在这里解释了您的问题以及在标记中使用 ASYNC 管道: Angular Observable Array Object Conversion

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM