【问题标题】:Unique usernames in FirebaseFirebase 中的唯一用户名
【发布时间】:2017-02-14 18:57:03
【问题描述】:

我一直试图在这里实现 Chris 的回答:Can I make Firebase use a username login process? 用于 Facebook 登录,但我似乎无法理解它。

到目前为止,我已尝试在 textField 上设置条件,但由于 Firebase 观察者异步工作,因此检查用户名是否存在于数据库中的条件将不起作用。

let usernameString = usernameTextField.text
let uid = FIRAuth.auth()?.currentUser?.uid

ref.runTransactionBlock({ (currentData: FIRMutableData) -> FIRTransactionResult in
    if var post = currentData.value as? [String : AnyObject], let uid = FIRAuth.auth()?.currentUser?.uid {

        let usernamesDictionary = post["usernames"] as! NSDictionary
        for (key, _) in usernamesDictionary {
            if key as? String == usernameString {
                print("username not available: \(key)")
            }
            else if usernameString == "" {
               print("Uh oh! Looks like you haven't set a username yet.")
            }
            else if key as? String != usernameString {
                print("username available: \(key)")
                print("All set to go!")

                let setValue: NSDictionary = [usernameString!: uid]
                post["usernames"] = setValue
                currentData.value = post  
            }
        }
        return FIRTransactionResult.successWithValue(currentData)
    }
    return FIRTransactionResult.successWithValue(currentData)
}

然后我尝试在数据库中创建 /usernames/ 节点并将规则设置为:

{
  "rules": {
    "usernames": {
      ".read": "auth != null",
      ".write": "newData.val() === auth.uid && !data.exists()"
    }
  }
}

现在这不会让我为数据库设置任何用户名。我对创建规则感到困惑,但我的重点是我需要一个注册流程,其中包含数据库中每个用户唯一的用户名数据。

【问题讨论】:

  • 你为什么要让用户名独一无二? Firebase Auth 内置了对大量提供商的支持,包括电子邮件/密码。它会为所有创建的帐户生成一个唯一的 UID。
  • @FibreChips 是的,但这些是自动生成的唯一 ID,而不是用户可以选择设置的用户名。
  • 您当前的方法有哪些不适用的地方?事务块应该触发(可能多次),但(结合安全规则)最终应该允许您安全地声明用户名。
  • @FrankvanPuffelen 现在由于安全规则,它不允许我设置用户名。事务块工作正常,但我的安全规则有问题。
  • 您真的在您的整个数据库上运行事务吗?在您关心的唯一级别上运行它怎么样:ref.child("usernames").child(usernameString)?如果您对其运行事务并且currentData 存在,则中止事务(因为用户名已被声明)。如果currentData 不存在,则返回您自己的 auth.uid 作为节点的新值。

标签: swift firebase firebase-realtime-database firebase-authentication


【解决方案1】:

在尝试我在相关帖子中找到的每个答案时,最简单的方法对我有用,即不让 Firebase 规则参与其中或在数据库中创建单独的用户名节点是不将 if/else 条件放入Firebase 观察者,而是使用 FIRDataSnapshot 的 exists() 方法。

现在这是诀窍,虽然我确实只使用简单的观察者尝试了 exists() 方法,但这对我没有帮助。我所做的是首先按顺序查询用户名,然后将用户名与 queryEqualToValue 匹配以过滤查询:

refUsers.queryOrderedByChild("username").queryEqualToValue(usernameString).observeSingleEventOfType(.Value , withBlock: {
            snapshot in

            if !snapshot.exists() {
                if usernameString == "" {
                    self.signupErrorAlert("Uh oh!", message: "Looks like you haven't set a username yet.")
                }
                else {

                    // Update database with a unique username.

                }
            }
            else {
                self.signupErrorAlert("Uh oh!", message: "\(usernameString!) is not available. Try another username.")
            }

        }) { error in
            print(error.localizedDescription)

        }
    }

这是对我有用的大多数答案中的第一次。但就目前而言,我不知道这是否会扩大规模。发布您的经验和最佳实践。他们将不胜感激。

【讨论】:

    猜你喜欢
    • 2017-03-29
    • 2016-05-16
    • 2020-02-06
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多