升级到 Firebase 5 并遇到身份验证问题。无法转换类型“(用户?,错误?)

Posted

技术标签:

【中文标题】升级到 Firebase 5 并遇到身份验证问题。无法转换类型“(用户?,错误?)【英文标题】:Upgraded to Firebase 5 and having Auth issues. Cannot convert value of type '(User?, Error?) 【发布时间】:2018-07-12 15:22:22 【问题描述】:

我刚刚为 Firebase 升级了我的 pod,但出现了大量错误。我使用了 Firebase Docs 网页上的 Docs,所以我能够修复其中的大部分。我遇到了这个错误,需要一些帮助。

这是我的错误:(我将它们标记为错误 1。和错误 2。)

    无法将类型“(用户?,错误?)->()”的值转换为预期的参数类型“AuthDataResultCallback?” (又名'可选()>')

    “用户?”类型的值没有成员“updateEmail”

这是我的 AuthService.Swift 代码:(所有相同的 Swift 代码,只是拆分以显示错误)

import Foundation
import Firebase

class AuthService 

    static func signIn(email: String, password: String, onSuccess: @escaping () -> Void, onError:  @escaping (_ errorMessage: String?) -> Void) 
        Auth.auth().signIn(withEmail: email, password: password, completion:  (user, error) in
            if error != nil 
                onError(error!.localizedDescription)
                return
            
            onSuccess()
        )

    

    static func signUp(username: String, email: String, password: String, imageData: Data, onSuccess: @escaping () -> Void, onError:  @escaping (_ errorMessage: String?) -> Void) 

错误 1。

Auth.auth().createUser(withEmail: email, password: 密码, 完成:(用户:用户?,错误:错误?)在

            if error != nil 
                onError(error!.localizedDescription)
                return
            

            let uid = user?.uid
            let storageRef = FIRStorage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("profile_image").child(uid!)

            storageRef.put(imageData, metadata: nil, completion:  (metadata, error) in
                if error != nil 
                    return
                
                let profileImageUrl = metadata?.downloadURL()?.absoluteString

                self.setUserInfomation(profileImageUrl: profileImageUrl!, username: username, email: email, uid: uid!, onSuccess: onSuccess)
            )
        )

    

    static func setUserInfomation(profileImageUrl: String, username: String, email: String, uid: String, onSuccess: @escaping () -> Void) 
        let ref = Database.database().reference()
        let usersReference = ref.child("users")
        let newUserReference = usersReference.child(uid)
        newUserReference.setValue(["username": username, "username_lowercase": username.lowercased(), "email": email, "profileImageUrl": profileImageUrl])
        onSuccess()
    

    static func updateUserInfor(username: String, email: String, imageData: Data, onSuccess: @escaping () -> Void, onError:  @escaping (_ errorMessage: String?) -> Void) 

错误 2。

Api.User.CURRENT_USER.updateEmail(email, completion: (error) in

            if error != nil 
                onError(error!.localizedDescription)
            else 
                let uid = Api.User.CURRENT_USER?.uid
                let storageRef = FIRStorage.storage().reference(forURL: Config.STORAGE_ROOF_REF).child("profile_image").child(uid!)

                storageRef.put(imageData, metadata: nil, completion:  (metadata, error) in
                    if error != nil 
                        return
                    
                    let profileImageUrl = metadata?.downloadURL()?.absoluteString

                    self.updateDatabase(profileImageUrl: profileImageUrl!, username: username, email: email, onSuccess: onSuccess, onError: onError)
                )
            
        )

    

    static func updateDatabase(profileImageUrl: String, username: String, email: String, onSuccess: @escaping () -> Void, onError:  @escaping (_ errorMessage: String?) -> Void) 
        let dict = ["username": username, "username_lowercase": username.lowercased(), "email": email, "profileImageUrl": profileImageUrl]
        Api.User.REF_CURRENT_USER?.updateChildValues(dict, withCompletionBlock:  (error, ref) in
            if error != nil 
                onError(error!.localizedDescription)
             else 
                onSuccess()
            

        )
    

    static func logout(onSuccess: @escaping () -> Void, onError:  @escaping (_ errorMessage: String?) -> Void) 
        do 
            try Auth.auth().signOut()
            onSuccess()

         catch let logoutError 
            onError(logoutError.localizedDescription)
        
    

【问题讨论】:

【参考方案1】:

如果您查看release notes,您会发现他们改变了一些东西。本质上,它们不再返回用户,而是返回另一个包含用户的对象 (AuthDataResult)。

这意味着您需要FIRAuthDataResultCallback。

【讨论】:

【参考方案2】:

Database5 的语法变化很大,

在error1中,你可以试试这个:

static func signUp(username:String, email:String, password: String, imageData:Data, onSuccess: @escaping () -> Void, onError: @escaping (_ errorMessage: String?) -> Void) 
    Auth.auth().createUser(withEmail: email, password: password)  (user , error) in
        if error != nil 
            onError(error!.localizedDescription)
            return
        
        //Here you have to change the uid 
        let uid = user?.user.uid
        //It should be Storage.storage().reference()
        let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOT_REF).child("profile_image").child(uid!)
        //storageRef.put was removed and it's changed be storage.putData 
        storageRef.putData(imageData, metadata: nil, completion:  (metadata, error) in
            if error != nil 
                return
            
            //downloadURL is changed too, you can read at documents of Firebase to know how to use this
            storageRef.downloadURL(completion:  (url, error) in
                if let error = error  
                    return
                else 
                    let profileImageUrl = url!.absoluteString
                    self.setUserInformation(profileImageUrl: profileImageUrl, username: username, email: email, uid: uid!, onSuccess: onSuccess)
                
            )
        )
    

而在error2中,它与error1同样的错误,你可以试试这个:

        Api.User.CURRENT_USER?.updateEmail(to: email, completion:  (error) in
        if error != nil 
            onError(error?.localizedDescription)
        else   
            let uid = Api.User.CURRENT_USER?.uid
            //Change here
            let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOT_REF).child("profile_image").child(uid!)
            //Change here
            storageRef.putData(imageData, metadata: nil, completion:  (metadata, error) in
                if error != nil 
                    return
                
                storageRef.downloadURL(completion:  (url, error) in
                    if let error = error 
                        return
                    else 
                        let profileImageUrl = url!.absoluteString
                        self.updateDatabase(profileImageUrl: profileImageUrl, username: username, email: email, onSuccess: onSuccess, onError: onError)
                    
                )
            )
        
    )


static func updateDatabase(profileImageUrl: String, username: String, email: String, onSuccess: @escaping () -> Void, onError: @escaping (_ errorMessage: String?) -> Void) 
    let dict = ["username": username, "username_lowercase": username.lowercased(), "email": email, "profileImageUrl": profileImageUrl]
    Api.User.REF_CURRENT_USER?.updateChildValues(dict, withCompletionBlock:  (error, ref) in
        if error != nil 
            onError(error?.localizedDescription)
        else 
            onSuccess()
        
    )



static func logOut(onSuccess: @escaping () -> Void, onError: @escaping (_ errorMessage: String?) -> Void) 
    do 
        try Auth.auth().signOut()
        onSuccess()
    catch let logoutError 
        onError(logoutError.localizedDescription)
    

你可以再次阅读 Firebase 的文档,看看有什么区别https://firebase.google.com/docs/ios/setup

【讨论】:

以上是关于升级到 Firebase 5 并遇到身份验证问题。无法转换类型“(用户?,错误?)的主要内容,如果未能解决你的问题,请参考以下文章

从 firebase 下载文件并上传到 Stripe 进行身份验证

Firebase 验证码检查失败并阻止用户进行身份验证

Firebase-tools 升级后 Firebase-functions 身份验证失败

Firebase 身份验证 - 登录用户为空

由于 Firebase 手机身份验证,App Store 被拒绝

从 Firebase 身份验证中删除用户