无法转换“ AuthDataResult”类型的值?到预期的参数类型“用户”

时间:2019-06-03 05:05:59

标签: swift firebase authentication login firebase-authentication

我正在尝试从用户模型中设置“当前”,以便以后可以使用current.username或current.uid等,但是我得到“无法转换'AuthDataResult类型的值?”到预期的参数类型“用户””错误。在过去的项目中,我能够按照最底部显示的教程进行操作。我现在拥有的代码显示在其上方。我在堆栈溢出时检查了与此有关的其他问题,但找不到对我有帮助的东西。

(用户模型)

import Foundation
import UIKit
import FirebaseDatabase.FIRDataSnapshot

class User: Codable {

    let uid: String
    let username: String

    init(uid: String, username: String){
        self.uid = uid
        self.username = username
    }

    init?(snapshot: DataSnapshot) {
        guard let dict = snapshot.value as? [String : Any],
            let username = dict[Constants.Dict.username] as? String
            else { return nil }

        self.uid = snapshot.key
        self.username = username
    }

    private static var _current: User?

    static var current: User {
        guard let currentUser = _current else {
            fatalError("Error: current user doesn't exist")
        }
        return currentUser
   }

    class func setCurrent(_ user: User, writeToUserDefaults: Bool = false) {
        if writeToUserDefaults {
            if let data = try? JSONEncoder().encode(user) {
                UserDefaults.standard.set(data, forKey: Constants.UserDefaults.currentUser)
            }
        }

        _current = user
    }
}

(当前项目-LoginVC)

@objc func handleSignIn() {
    guard let email = emailField.text else { return }
    guard let pass = passwordField.text else { return 

    Auth.auth().signIn(withEmail: email, password: pass) { user, error in
        if error == nil && user != nil {
            --> --> ERROR HERE "user" !!
            User.setCurrent(user, writeToUserDefaults: true)
            self.dismiss(animated: false, completion: nil)
        } else {
            print("Error logging in: \(error!.localizedDescription)")
        }
    }
}

(更新的解决方案)

Auth.auth().signIn(withEmail: email, password: pass) { user, error in
        if user?.user != nil {

            let user = user!.user

            UserService.show(forUID: user.uid) { (user) in
                User.setCurrent(user!, writeToUserDefaults: true)

                self.dismiss(animated: false, completion: nil)
            }
            ...

1 个答案:

答案 0 :(得分:0)

看来,您只是弄乱了两种不同的方法。在您过去的项目中,它是 FirebaseUI-iOS 的方法:

func authUI(_ authUI: FUIAuth, didSignInWith user: FIRUser?, error: Error?)

来自协议“ FUIAuthDelegate”。

顺便说一下,此方法现在在firebase sources中声明为“不赞成使用”:

- (void)authUI:(FUIAuth *)authUI
    didSignInWithUser:(nullable FIRUser *)user
                error:(nullable NSError *)error
__attribute__((deprecated("Instead use authUI:didSignInWithAuthDataResult:error:")));

如您所见,它具有名为“ user”的“ FIRUser *”类型的参数。

但是在当前项目中,您使用 firebase-ios-sdk 的“ Auth”类的方法“ signIn”。让我们在sources of Firebase中查找“ signIn”的签名:

    - (void)signInWithEmail:(NSString *)email
                   password:(NSString *)password
                 completion:(nullable FIRAuthDataResultCallback)completion {

where "FIRAuthDataResultCallback" is

/** @typedef FIRAuthDataResultCallback
    @brief The type of block invoked when sign-in related events complete.
    @param authResult Optionally; Result of sign-in request containing both the user and
       the additional user info associated with the user.
    @param error Optionally; the error which occurred - or nil if the request was successful.
 */
typedef void (^FIRAuthDataResultCallback)(FIRAuthDataResult *_Nullable authResult,
                                          NSError *_Nullable error)
    NS_SWIFT_NAME(AuthDataResultCallback);

因此它具有类型为“ FIRAuthDataResult *”的FIRST参数,名为“ authResult”(闭包参数的命名在现代Swift中没有保留!)。您将此参数命名为“用户”,并对其类型做出了错误的假设-用户。

什么是“ FIRAuthDataResult *”? Let's look to sources once more

NS_SWIFT_NAME(AuthDataResult)
@interface FIRAuthDataResult : NSObject

/**...*/
- (instancetype)init NS_UNAVAILABLE;

/** @property user
    @brief The signed in user.
 */
@property(nonatomic, readonly) FIRUser *user;

/** @property additionalUserInfo
    @brief If available contains the additional IdP specific information about signed in user.
 */
@property(nonatomic, readonly, nullable) FIRAdditionalUserInfo *additionalUserInfo;

@end

所以这只是用户和其他信息的容器。

我认为,这就是您当前代码可编译的方式:

@objc func handleSignIn() {
    guard let email = emailField.text else { return }
    guard let pass = passwordField.text else { return 

    Auth.auth().signIn(withEmail: email, password: pass) { authDataResult, error in
        guard let authDataResult = authDataResult,
            let user = authDataResult.user,
            error == nil else {
            print("Error logging in: \(error?.localizedDescription ?? "no description")")
            return
        }
        User.setCurrent(user, writeToUserDefaults: true)
        self.dismiss(animated: false, completion: nil)
    }
}

免责声明:我并没有真正尝试编译它!