Ios 使用完成处理程序创建Firebase登录函数

Ios 使用完成处理程序创建Firebase登录函数,ios,swift,firebase,firebase-authentication,completionhandler,Ios,Swift,Firebase,Firebase Authentication,Completionhandler,我想让全局func登录,我可以在我的应用程序中使用,但我的问题是,我需要在创建用户后调用一些函数。我想我可以使用一个完成处理程序,但我这样尝试了一下,这给了我一个错误: static func signIn(credentials: Any?, username: String, finished: () -> Void){ Auth.auth().signIn(with: credentials as! AuthCredential, completion: { (user, e

我想让全局
func登录
,我可以在我的应用程序中使用,但我的问题是,我需要在创建用户后调用一些
函数
。我想我可以使用一个
完成处理程序
,但我这样尝试了一下,这给了我一个错误:

static func signIn(credentials: Any?, username: String, finished: () -> Void){
    Auth.auth().signIn(with: credentials as! AuthCredential, completion: { (user, error) in
        if error != nil {
            Utilities.showErrorPopUp(labelContent: "Fehler bei Kontoerstellung", description: error!.localizedDescription)
        } else {
            //user was created successfully; store name, username and UID
            let db = Firestore.firestore()

            let userID = user!.user.uid

            db.collection("users").document(userID).setData(["username": username, "uid": user!.user.uid]) { (error) in
                if error != nil {
                    Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                }
            }
            // generate empty "Main Wishlist"
            db.collection("users").document(userID).collection("wishlists").document("Main Wishlist").setData(["name": "Main Wishlist", "listIDX": 1]) { (error) in
                if error != nil {
                    Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                }
            }

            // set user status to logged-in
            UserDefaults.standard.setIsLoggedIn(value: true)
            UserDefaults.standard.synchronize()

            finished()

        }
    })
}
错误:

转义闭包捕获非转义参数“finished”

更改之前,我的
函数
如下所示:

Auth.auth().signIn(with: credentials, completion: { (user, error) in
                    if error != nil {
                        Utilities.showErrorPopUp(labelContent: "Fehler bei Kontoerstellung", description: error!.localizedDescription)
                    } else {
                        //user was created successfully; store name, username and UID
                        let db = Firestore.firestore()

                        let userID = user!.user.uid

                        db.collection("users").document(userID).setData(["username": username, "uid": user!.user.uid]) { (error) in
                            if error != nil {
                                Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                            }
                        }
                        // generate empty "Main Wishlist"
                        db.collection("users").document(userID).collection("wishlists").document("Main Wishlist").setData(["name": "Main Wishlist", "listIDX": 1]) { (error) in
                            if error != nil {
                                Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                            }
                        }

                        // set user status to logged-in
                        UserDefaults.standard.setIsLoggedIn(value: true)
                        UserDefaults.standard.synchronize()

                        // stop animation
                        self.logoAnimation.stop()

                        //transition to home
                        self.transitionToHome()
                    }
                })
            }
signIn(credentials: credentials, username: someString, finished: { (done) in

    if done { // success
        ...
    } else { // failure
        ...
    }

}
正如您在本例中看到的,我正在调用
self.logoAnimation.stop()
self.transitionHome()

当用户注册时,我如何能够超越方法,但仍然调用方法


如果有什么不清楚的地方,请告诉我:)

编辑:我添加了批写入

static func signIn(credentials: Any?, username: String, finished: @escaping (_ done: Bool) -> Void) {

    guard let credentials = credentials as? AuthCredential else {

        finished(false)
        return

    }

    Auth.auth().signIn(with: credentials, completion: { (result, error) in

        if let userId = result?.user.uid { // successfully signed in

            let batch = Firestore.firestore().batch()

            batch.setData(["username": username, "uid": userId], forDocument: Firestore.firestore().collection("users").document(userId), merge: true)
            batch.setData(["name": "Main Wishlist", "listIDX": 1], forDocument: Firestore.firestore().collection("users").document(userId).collection("wishlists").document("Main Wishlist"), merge: true)

            batch.commit { (error) in

                if let error = error {
                    print(error)
                    // maybe sign user out and on completion call finished(false)
                    // whatever you do, you must call finished(false) at some point
                } else {

                    UserDefaults.standard.setIsLoggedIn(value: true)
                    UserDefaults.standard.synchronize()
                    finished(true) // sign-in process complete

                }

            }

        } else { // could not sign in

            if let error = error {
                print(error)
            }
            finished(false)

        }

    })

}
对此方法的调用如下所示:

Auth.auth().signIn(with: credentials, completion: { (user, error) in
                    if error != nil {
                        Utilities.showErrorPopUp(labelContent: "Fehler bei Kontoerstellung", description: error!.localizedDescription)
                    } else {
                        //user was created successfully; store name, username and UID
                        let db = Firestore.firestore()

                        let userID = user!.user.uid

                        db.collection("users").document(userID).setData(["username": username, "uid": user!.user.uid]) { (error) in
                            if error != nil {
                                Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                            }
                        }
                        // generate empty "Main Wishlist"
                        db.collection("users").document(userID).collection("wishlists").document("Main Wishlist").setData(["name": "Main Wishlist", "listIDX": 1]) { (error) in
                            if error != nil {
                                Utilities.showErrorPopUp(labelContent: "Fehler", description: error!.localizedDescription)
                            }
                        }

                        // set user status to logged-in
                        UserDefaults.standard.setIsLoggedIn(value: true)
                        UserDefaults.standard.synchronize()

                        // stop animation
                        self.logoAnimation.stop()

                        //transition to home
                        self.transitionToHome()
                    }
                })
            }
signIn(credentials: credentials, username: someString, finished: { (done) in

    if done { // success
        ...
    } else { // failure
        ...
    }

}

谢谢你的回答!关于
交易
;我以为在读写新数据时会用到它们,但在这里我只想创建用户并设置所有用户都具有的标准值。@Chris抱歉,有时我一般使用术语transaction。你说得对,我想说的是批量写作。批处理写入是另一种原子Firestore操作。好吧,以前从未使用过批处理写入,但在我的情况下似乎有意义。但我仍然会使用您的结构形式回答,对吗?@Chris Dispatching仅用于多个异步操作,但批写入是单个异步操作。在我最初的回答中,我们对数据库执行了两次单独的写操作,产生了两次单独的异步返回。调度所做的一切就是记录我们输入它(写入前输入)和离开它(写入完成后离开)的次数,以及它们匹配的时间(输入两次,离开两次),它调用
notify
方法,该方法是它的完成处理程序。@Chris
setData
不合并将用您提供的数据覆盖整个文档
setData
with merge将数据与文档集成(并保留文档中的其他字段)。如果文档不存在,
setData
(带合并或不带合并)将创建文档<另一方面,如果文档不存在,则code>updateData将失败。如果您知道该文档存在,
updateData
是一种方法。如果文档可能不存在,
setData