【问题标题】:How can I repeat a Firestore query until a condition is met?如何重复 Firestore 查询直到满足条件?
【发布时间】:2019-11-07 12:11:08
【问题描述】:

因此,我正在将用户信息存储在我的数据库中,除了从 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();
      }
    })

【问题讨论】:

  • 谁保证第二次生成profileID不存在?它不会 100% 解决问题,但我建议将时间戳添加到配置文件 ID 以解决它。
  • 这就是为什么我要重复它直到生成的 profileID 是唯一的。由于我使用的是 10 位数字,因此大约有 100 亿种不同的组合,因此它始终是唯一的。

标签: javascript angular google-cloud-firestore angularfire2


【解决方案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 作为用户集合中其文档的键,而不是您知道使用的任何键。

【讨论】:

  • 如果您使用的是 async/await,则根本不需要递归。只需将 getRandomProfileId 设为异步函数,并在没有找到 ID 时循环,每次等待查询结果。
  • 好电话。我最初在想如何在没有递归的情况下做到这一点,后来才想到async/await。这种组合确实使这变得简单得多。我添加了一个例子。
  • 经过编辑简化了一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 2021-10-27
  • 2013-12-28
  • 2020-12-18
  • 2021-09-05
  • 2019-11-10
相关资源
最近更新 更多