【问题标题】:Swift closures and error handlingSwift 闭包和错误处理
【发布时间】:2019-01-28 00:53:20
【问题描述】:

你好,我需要一些关于函数和或可能在该函数中的闭包的帮助。我希望我的函数检查 firestore 用户集合中的重复文档(用户名)。如果找到重复项,我想显示一条消息,如果未找到重复项,则创建一个新用户。我有以下代码:

func checkIfUserExists(username: String, completion: @escaping (Bool) -> Void) {
    let docRef = db.collection("users").document(username)
    docRef.getDocument { (document, error) in
        if error != nil {
            print(error)
        } else {
            if let document = document {
                if document.exists {
                    completion(true)
                } else {
                    completion(false)
                }
            }
        }
    }
} 

我调用函数:

if let username = textField.text, username.count > 8 {              // Username needs to be more then 8 Char
    checkIfUserExists(username: username) { (doesExist) in
        if doesExist {
            print("user exists")
        } else {
            print("new User can be created")
        }
    }
} else {
    print("Username needs to be more then 8 char")
} 

}

它有效,但我觉得这不是好的做法,我正在走弯路。这是正确的做法吗?

【问题讨论】:

    标签: swift function firebase closures google-cloud-firestore


    【解决方案1】:

    我认为您现在的操作方式应该可以正常工作,但另一个避免您在写入之前读取数据库的方法是使用安全规则。例如,如果这是您的 users 集合的结构...

    users: [
       username1: { // doc ID is the username
          userid: abcFirebaseUserId, // a field for the uid of the owner of the username
          //...etc
       }
    ]
    

    ...那么您可以使用以下规则:

    match /users/{username} {
      allow create: if request.auth.uid != null;              
      allow update, delete: if resource.data.userId = request.auth.uid;
    }
    

    这允许任何经过身份验证的用户创建新用户名,但只有该用户名的所有者可以更新或删除它。如果您不允许用户更改他们的用户名,您甚至不必担心第二条规则。然后,在客户端中,您可以直接创建用户名,如下所示:

    func createUsername(username: String, completion: @escaping (String?) -> Void) {
        guard let userId = Auth.auth().currentUser.uid else {
            completion("no current user")
            return
        }
        let docRef = db.collection("users").document(username)
        docRef.setData(data:[userId: userId]) { error in
            if let error = error {
                completion(error.debugDescription)
            } else {
                completion(nil)
            }
        }
    } 
    

    这会将新用户名写入数据库,如果有错误,则将错误传递给闭包。如果用户名已经存在,则会出现insufficient permissions 错误。在检查用户是否存在时,您可以根据需要显示错误或提醒用户。

    createUsername(username: username) { err in
        if let err = err {
            print("user exists")
        } else {
            print("new User has been created")
        }
    }
    

    不过只是一个建议。我认为你现在这样做的方式也很好!

    【讨论】:

    • 您好 Jen,感谢您的建议。我仍然需要快速学习很多关于闭包的知识,感谢您的回答,我理解得更好了:) 我将检查我可以在我的代码中实现的内容:在创建用户之前我想要实现的是检查用户是否存在,然后在运行中(textfield -> editingChanged)如果用户被占用,则显示一个✘,如果用户名可用,则显示一个✓,这样用户就不必先按下按钮。为了充分理解,我可以更好地命名我的 cmets :)
    • 顺便说一句......通过调用函数你的意思是 createUsername(username: username) 对吗? :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    相关资源
    最近更新 更多