Javascript 向Firestore添加字段必须唯一的文档

Javascript 向Firestore添加字段必须唯一的文档,javascript,firebase,google-cloud-firestore,Javascript,Firebase,Google Cloud Firestore,假设不同设备上的两个用户同时执行以下操作 用户一: db.collection('agents').where('phone','==','9876543210') .get() .then(function(querySnapshot) { let agents = []; querySnapshot.forEach(function(doc) { agents.push(doc.data()); });

假设不同设备上的两个用户同时执行以下操作

用户一:

db.collection('agents').where('phone','==','9876543210')
  .get()
  .then(function(querySnapshot) {
        let agents = [];
        querySnapshot.forEach(function(doc) {
            agents.push(doc.data());
        });

        if(agents.length > 0){
          agentExists();
        }
        else{
          db.collection('agents').add({
            firstName: "ABC",
            lastName: "XYZ",
            phone: "9876543210"
          })
          .then(function(){
             agentAdded();
          });
        }
  })
  .catch(function(err){
     console.log(err);
  });
用户二:

db.collection('agents').where('phone','==','9876543210')
  .get()
  .then(function(querySnapshot) {
        let agents = [];
        querySnapshot.forEach(function(doc) {
            agents.push(doc.data());
        });

        if(agents.length > 0){
          agentExists();
        }
        else{
          db.collection('agents').add({
            firstName: "MNO",
            lastName: "PQR",
            phone: "9876543210"
          })
          .then(function(){
             agentAdded();
          });
        }
  })
  .catch(function(err){
     console.log(err);
  });
当用户试图添加具有不同名字和姓氏但电话号码相同的代理信息时,代码的编写方式使first query搜索号码,如果号码存在,则代理不会添加到集合中,如果没有,则添加。但是当两个用户同时执行上述操作时,两个代理都被添加,而我的要求是只允许添加一个代理,因为电话号码将被复制

尝试过的其他解决方案:
尝试使用onSnapshot方法获取实时更新,但正如我们所知,firestore sdk首先将文档添加到缓存中,然后添加到后端,因此当添加新代理时,它首先显示代理退出,然后显示代理添加。

在这种情况下,由于电话号码在该集合中显然是唯一的,它还应该是文档ID。如果您使用电话号码作为文档ID,那么您可以使用确保只有一个客户端可以创建该文档,以避免竞争条件

如果不使用电话号码作为文档ID,我认为没有办法确保电话号码作为普通字段的唯一性,因为Firestore不提供对任意查询结果执行事务的方法


如果您不能使用电话号码作为文档ID,那么您需要一种方法来清除任何重复项,也许可以使用服务器时间戳来确定最后添加的是哪一个。

如果您不想保留电话号码作为密钥,那么您应该使用事务。

谢谢@DougStevenson,嗯,我已经考虑过使用交易,但我仅限于不使用电话号码作为文档ID。我认为您没有其他选择。