如何重复Firestore查询,直到满足条件?

时间:2019-06-25 15:43:14

标签: javascript angular google-cloud-firestore angularfire2

因此,我正在努力在数据库中存储用户信息,除了从Firebase用户获得的标准数据外,我还想添加自己的自定义数据。我正在为每个用户设置一个个人资料页面,我想生成一个随机的10位数字作为他们的个人资料ID。然后,将其存储在数据库中,以防万一。但是,我需要它们是唯一的数字,并且不能重复使用,因此我试图查询数据库以检查生成的profileID是否已在使用,如果是,则生成另一个。但是,除了可能使用循环外,我无法弄清楚如何在Firestore中重复查询,但这似乎行不通。

    const usersRef: AngularFirestoreCollection = this.afs.collection('users');

    var query = usersRef.ref.where("profileID", '==', profileID);
    query.get().then((querySnapshot) => {
      if (!querySnapshot.empty) {
        profileID = this.getRandomProfileID();
      }
    })

1 个答案:

答案 0 :(得分:1)

像这样的递归函数似乎是解决方法:

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);

但是这种方法仍然需要考虑一些事情:

  1. 另一个用户可能会在您生成,检查和实际创建它之间生成相同的配置文件ID。如果这是一个问题,您可能应该对上述功能使用事务,并使其创建配置文件。如果不是现实的问题,您仍应在安全规则中确保没有用户可以覆盖另一个用户已经创建的文档。

  2. 如果要在很多地方使用自己的个人资料ID来标识用户,请考虑创建一个附加集合,其中每个文档名称/ ID是个人资料ID,而文档内容是关键进入用户集合。如果要通过用户的个人资料ID唯一地标识用户,请考虑使用个人资料ID作为用户集合中文档的密钥,而不要使用您知道的任何密钥。