firebase - 云Firestore : Enforcing Unique User Names

标签 firebase google-cloud-firestore

问题

我已经多次看到这个问题(也在 Firebase 实时数据库的上下文中),但我还没有看到令人信服的答案。问题陈述相当简单:

How can (authenticated) users choose a username that hasn't been taken yet?

首先,原因:用户经过身份验证后,他们将拥有唯一的用户 ID。然而,许多网络应用程序让用户选择“显示名称”(用户希望在网站上显示的方式),以保护用户的个人数据(如真实姓名)。

用户集合

给定如下所示的数据结构,可以为每个用户存储用户名以及其他数据:

/users  (collection)
    /{uid}  (document)
        - name: "<the username>"
        - foo: "<other data>"

但是,没有什么可以阻止其他用户(具有不同的 {uid})在其记录中存储相同的name。据我所知,没有“安全规则”允许我们检查名称是否已被其他用户使用。

注意:客户端检查是可能的,但不安全,因为恶意客户端可能会忽略检查。

反向映射

流行的解决方案是创建具有反向映射的集合:

/usernames  (collection)
    /{name}  (document)
       - uid: "<the auth {uid} field>"

鉴于此反向映射,可以编写安全规则来强制用户名尚未被占用:

match /users/{userId} {
  allow read: if true;
  allow create, update: if
      request.auth.uid == userId &&
      request.resource.data.name is string &&
      request.resource.data.name.size() >= 3 &&
      get(/PATH/usernames/$(request.resource.data.name)).data.uid == userId;
}

并强制用户首先创建用户名文档:

match /usernames/{name} {
  allow read: if true;
  allow create: if
      request.resource.data.size() == 1 &&
      request.resource.data.uid is string &&
      request.resource.data.uid == request.auth.uid;
}

我相信解决方案已经成功了一半。然而,仍有一些 Unresolved 问题。

剩余问题

这个实现已经相当复杂,但它甚至没有解决用户想要更改用户名的问题(需要记录删除或更新规则等)

另一个问题是,没有什么可以阻止用户在 usernames 集合中添加多个记录,从而有效地抢夺所有好的用户名来破坏系统。

所以问题是:

  • 是否有更简单的解决方案来强制使用唯一的用户名?
  • 如何防止向用户名集合发送垃圾邮件?
  • 如何使用户名检查不区分大小写?

我还尝试强制 users 存在,并使用/usernames 集合的另一个 exists() 规则,然后提交批量写入操作,但是,这并没有似乎不起作用(“权限缺失或不足”错误)。

另一个注意事项:我已经看到了带有客户端检查的解决方案。 但是这些是不安全的。任何恶意客户端都可以修改代码并忽略检查。

最佳答案

Twitter 上的

@asciimike 是 Firebase 安全规则开发人员。 他说,目前还没有办法强制文档上的键的唯一性。 https://twitter.com/asciimike/status/937032291511025664

由于 firestore 基于 Google Cloud datastore,因此它继承了此问题。自 2008 年以来,这是一个长期存在的要求。 https://issuetracker.google.com/issues/35875869#c14

但是,您可以通过使用 firebase 函数 和一些严格的安全规则来实现您的目标。

您可以在 Medium 上查看我提出的整个解决方案。 https://medium.com/@jqualls/firebase-firestore-unique-constraints-d0673b7a4952

关于firebase - 云Firestore : Enforcing Unique User Names,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47405774/

相关文章:

firebase - 当 Firebase Functions 发送时,Timestamp 在 BigQuery 上返回错误

javascript - 带有 FCM 推送通知的 Angular Service worker

node.js - Rxjava2如何简洁地将结果从前一个 Node 返回到链中的下一个 Node

android - 如何使用 Firebase 推送消息取决于用户在设备上的帐户状态

firebase - 抽象服务类中的 Flutter Firestore 分页

flutter - 如何将 Firestore 时间戳转换为 Dart 日期时间

javascript - 按时间戳查询 firestore 中的数据

swift - 使用 iOS Swift 的 Firebase2 Facebook 身份验证(没有 FBSDKLoginButton)

android - 如何使用 FieldValue.serverTimestamp() 在 android 中自定义模型类

swift - 使 SearchBar 快速检索准确的数据