在创建集合之前检查Firestore中是否存在集合

时间:2017-10-19 18:14:47

标签: android firebase race-condition google-cloud-firestore

上下文:我的应用程序目前允许用户使用用户名创建帐户。点击confirm - 创建帐户后,会在用户名上运行检查,以验证它是否作为usernames集合中的文档存在,即此仅允许应用程序中的唯一用户名。

创建视图后,用户名被添加到地图中 - 在用户按下confirm按钮之前(我知道这是潜在问题)

public static void getAllNonAvailableUsernames() {
    FirebaseFirestore.getInstance()
            .collection("usernames")
            .get().addOnCompleteListener(task -> {
                 List<DocumentSnapshot> snapshots = task.getResult().getDocuments();
                 for (DocumentSnapshot snap : snapshots) {
                     usedUsernames.put(snap.getId(), snap.get("owner"));
                 }
             });
}
当两个用户碰巧选择相同的用户名进行注册时,会出现

问题。最后一个请求将被处理并覆盖文档中的owner字段,允许两个用户拥有相同的用户名

Format of the usernames collection

我不确定如何解决此问题,因为在usernames集合中检索所有文档可能无法在验证发生之前完成。

1 个答案:

答案 0 :(得分:1)

如果您的用户必须拥有唯一的用户名,那么正确执行此操作的唯一方法是使用transaction。在您的交易中,请阅读您尝试注册的特定用户名:

  • 如果用户名存在:请求用户输入其他用户名
  • 否则设置用户记录。

事务保证两个操作都以原子方式发生。

请注意,Firestore事务仅在联机时有效。如果您尝试在没有网络连接的情况下运行事务,则会在尝试几次后失败。在这种情况下,您需要提示用户在有网络连接时进行注册。