内部有闭包的递归函数

Recursive func with closure inside

我正在尝试在我的 Firebase 数据库中生成一个唯一的 8 位用户 ID 作为我的用户的密钥,而不是在 Firebase 中创建的 28 位用户 ID。

在函数中我想生成随机变量,然后对照数据库检查它是否存在。如果它存在于数据库中,我想递归调用直到创建唯一键。

我试过了

func createUniqueID() -> String {

    let userID = generateUserID()

    let ref = Database.database().reference(withPath: "users")
    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.hasChild(userID) {
            return createUniqueID() //errors here
        }
        else {
            return userID //errors here
        }
    })
}

但是我在 firebase 闭包 "Unexpected non-void return value in void function"

的 return 行都收到了错误

我尝试将其作为内联函数

func wtf() -> String {

    let userID = "123456"//generateUserID()

    func doesUserIDExistAlready(userID: String, complete: @escaping(String) -> ()) {

        let ref = Database.database().reference(withPath: "users")
        ref.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChild(userID) {
                complete( self.wtf() )
            }
            else {
                complete( userID )
            }
        })
    }

    doesUserIDExistAlready(userID: userID) { userID in
        return userID //warning here
    }
}

但我在 return 用户 ID

上收到 "Expression of type 'String' is unused" 警告

我也试过使用没有完成的内联函数但是return正在处理一个字符串

func wtf2() -> String {

    let userID = "123456"//generateUserID()

    func doesUserIDExistAlready(userID: String) -> String {

        let ref = Database.database().reference(withPath: "users")
        ref.observeSingleEvent(of: .value, with: { (snapshot) in
            if snapshot.hasChild(userID) {
                return self.wtf2() //errors here
            }
            else {
                return userID //errors here
            }
        })
    }

    return doesUserIDExistAlready(userID: userID)
}

但我在 firebase 闭包 "Unexpected non-void return value in void function"

的两行 return 上也出现错误

这可以吗?

向 Firebase 请求数据是一个异步操作,因此createUniqueID不能return立即String。您可以接受 completion 闭包到 "return" 调用者的 ID(就像 observeSingleEvent 使用闭包给您值一样)。

func createUniqueID(_ completion: (String) -> Void) {

    let userID = generateUserID()

    let ref = Database.database().reference(withPath: "users")
    ref.observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.hasChild(userID) {
            createUniqueID(completion)
        }
        else {
            completion(userID)
        }
    })
}