首页 > 解决方案 > 无法转换“AuthDataResult”类型的值?到预期的参数类型“用户”

问题描述

我正在尝试从我的用户模型设置“当前”,以便以后可以使用 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)
            }
            ...

标签: swiftfirebaseauthenticationloginfirebase-authentication

解决方案


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

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

来自协议“FUIAuthDelegate”。

顺便说一句,这个方法现在在firebase 源中声明为“已弃用” :

- (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”方法。让我们在Firebase的来源中寻找“​​signIn”的签名:

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

其中“FIRAuthDataResultCallback”是

/** @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);

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

什么是“FIRAuthDataResult *”?让我们再次查看来源

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)
    }
}

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


推荐阅读