Javascript 在满足条件之前,我如何重复Firestore查询?

Javascript 在满足条件之前,我如何重复Firestore查询?,javascript,angular,google-cloud-firestore,angularfire2,Javascript,Angular,Google Cloud Firestore,Angularfire2,因此,我正在开发一个将用户信息存储在数据库中的数据库,除了从Firebase用户那里获得的标准数据之外,我还想添加自己的自定义数据。我正在为我的每个用户设置一个配置文件页面,我想生成一个随机的10位数字作为他们的配置文件ID。然后我将其存储在数据库中,以备需要。但是,我需要它们是唯一的数字,并且不重复,因此我尝试查询数据库,以检查我生成的profileID是否已经在使用,如果已经在使用,则生成另一个。然而,除了使用循环之外,我不知道如何在Firestore中重复查询,但这似乎不起作用 const

因此,我正在开发一个将用户信息存储在数据库中的数据库,除了从Firebase用户那里获得的标准数据之外,我还想添加自己的自定义数据。我正在为我的每个用户设置一个配置文件页面,我想生成一个随机的10位数字作为他们的配置文件ID。然后我将其存储在数据库中,以备需要。但是,我需要它们是唯一的数字,并且不重复,因此我尝试查询数据库,以检查我生成的profileID是否已经在使用,如果已经在使用,则生成另一个。然而,除了使用循环之外,我不知道如何在Firestore中重复查询,但这似乎不起作用

const usersRef:AngularFirestoreCollection=this.afs.collection('users');
var query=usersRef.ref.where(“profileID”、“==”、profileID);
query.get().then((querySnapshot)=>{
如果(!querySnapshot.empty){
profileID=this.getRandomProfileID();
}
})

像这样的递归函数似乎是可行的:

function getRandomProfileID() {
  return new Promise(function(resolve, reject) {
    var profileID = .... 

    var query = usersRef.ref.where("profileID", '==', profileID);
    query.get().then((querySnapshot) => {
      if (!querySnapshot.empty) {
        this.getRandomProfileID();
      }
      else {
        resolve(profileID);
      }
    })
  })
}
然后你会用以下方式来称呼它:

getRandomProfileID().then(function(profileID) {
  console.log(profileID);
});
或者,如果您使用的是更现代的JavaScript版本:

var profileID = await getRandomProfileID();
console.log(profileID);
正如Doug指出的,使用
async
/
await
甚至可以完全不使用递归函数:

while (true) {
    let profileID = .... 
    let snapshot = await usersRef.ref.where("profileID", '==', profileID).get()
    if (!snapshot.empty) {
        break;
    }
}
console.log("Found unique ID: " + profileID);
但有一些事情需要考虑:

  • 另一个用户可能会在您生成并检查配置文件ID和实际创建它之间生成相同的配置文件ID。如果这是一个问题,您可能应该为上述函数使用一个事务,并让它创建概要文件文档。如果这不是一个现实问题,您仍然应该在安全规则中确保任何用户都不能覆盖其他用户已经创建的文档

  • >P>如果您要在很多地方使用您自己的配置文件ID来标识用户,请考虑创建一个附加集合,其中每个文档名称/ID是配置文件ID,文档内容是用户集合中的密钥。如果你要通过他们的配置文件ID唯一地标识用户,考虑使用配置文件ID作为他们在用户集合中的文档的密钥,而不是使用你知道的任何密钥。


    谁保证您第二次生成profileID时不存在?它不会100%解决这个问题,但我建议将时间戳添加到profileID中来解决它。这就是为什么我要重复它,直到生成的profileID是唯一的。因为我使用的是10位数字,所以大约有100亿个不同的组合,所以它总是唯一的。如果使用的是async/await,则根本不需要递归。只需将getRandomProfileId设置为异步函数,并在找不到ID时循环,每次都等待查询结果。调用很好。我最初在考虑如何在没有递归的情况下实现这一点,后来才想到
    async
    /
    await
    。这种结合确实使这变得简单得多。我添加了一个这样的例子。编辑以简化一点。