无法转换“AuthResultCallback”类型的值?
Posted
技术标签:
【中文标题】无法转换“AuthResultCallback”类型的值?【英文标题】:Cannot convert value of type `AuthResultCallback`? 【发布时间】:2020-06-06 11:44:49 【问题描述】:我知道其他类似的问题,但它们分别与 Auth.auth().signIn
和 signUp
有关,其中函数中存在完成处理程序参数。
我试图在我的 SessionStore
类的匿名函数中包含一个登录,以便我的应用程序观察用户的状态,即他是否登录(匿名或其他方式)或退出,并相应地显示相关视图。
但是,当尝试将匿名注册添加到我的 SessionStore
课程时,我收到以下错误:
Cannot convert value of type 'AuthResultCallback' (aka '(Optional<User>, Optional<Error>) -> ()') to expected argument type 'AuthDataResultCallback?' (aka 'Optional<(Optional<AuthDataResult>, Optional<Error>) -> ()>')
我的代码如下:
class SessionStore: ObservableObject
var didChange = PassthroughSubject<SessionStore, Never>()
@Published var session: User? didSet self.didChange.send(self)
var handle: AuthStateDidChangeListenerHandle?
func listen()
handle = Auth.auth().addStateDidChangeListener( (auth, user) in
if let user = user
self.session = User(uid: user.uid, email: user.email)
else
self.session = nil
)
func signUp(email: String, password: String, handler: @escaping AuthDataResultCallback)
Auth.auth().createUser(withEmail: email, password: password, completion: handler)
func signIn(email: String, password: String, handler: @escaping AuthDataResultCallback)
Auth.auth().signIn(withEmail: email, password: password, completion: handler)
func signOut()
do
try Auth.auth().signOut()
self.session = nil
catch
print("Error signing user out")
func signUpAnonymously(handler: @escaping AuthResultCallback)
Auth.auth().signInAnonymously(completion: handler) // **ERROR APPEARS HERE**
func unbind()
if let handle = handle
Auth.auth().removeStateDidChangeListener(handle)
deinit
unbind()
struct User
var uid: String
var email: String?
init(uid: String, email: String?)
self.uid = uid
self.email = email
谁能告诉我如何解决这个错误?
【问题讨论】:
两个完成处理程序不同typealias AuthDataResultCallback = (FIRAuthDataResult?, Error?) -> Void
signInAnonymously(completion:)
的声明是什么?它似乎想要一个AuthDataResultCallback
参数,而你给它一个AuthResultCallback
一个。那是正常的,有不匹配的。
typealias AuthResultCallback = (FIRUser?, Error?) -> Void
请注意,函数 func signUpAnonymously(handler:
没有从代码中的其他任何地方调用,因此我们不知道它是如何使用的或传入了什么。而且,@Larme 提到,这个@escaping AuthResultCallback
不匹配,因为 .signInAnonymously 期待 AuthDataResultCallback
【参考方案1】:
您粘贴的代码 sn-p 来自过时的教程。从 Xcode 11 beta 5 开始,您不再需要使用 PassthroughSubject
来发送有关属性更改的通知。 Sarun's blog post 有一个很棒而简洁的部分介绍了哪些变化,我鼓励你阅读它。
还请注意,如果您只关心用户的 ID 和他们的电子邮件地址,则不需要定义自己的 User
类,因为这些属性已经在 Firebase 自己的 User
类型中定义(通过实现UserInfo
协议)。
这是一个 sn-p,它展示了如何实现您感兴趣的回调(请参阅registerStateListener
)。
class AuthenticationService: ObservableObject
@Published var user: User?
private var handle: AuthStateDidChangeListenerHandle?
init()
registerStateListener()
func signIn()
if Auth.auth().currentUser == nil
Auth.auth().signInAnonymously()
func signOut()
do
try Auth.auth().signOut()
catch
print("Error when trying to sign out: \(error.localizedDescription)")
func updateDisplayName(displayName: String, completionHandler: @escaping (Result<User, Error>) -> Void)
if let user = Auth.auth().currentUser
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = displayName
changeRequest.commitChanges error in
if let error = error
completionHandler(.failure(error))
else
if let updatedUser = Auth.auth().currentUser
print("Successfully updated display name for user [\(user.uid)] to [\(updatedUser.displayName ?? "(empty)")]")
// force update the local user to trigger the publisher
self.user = updatedUser
completionHandler(.success(updatedUser))
private func registerStateListener()
if let handle = handle
Auth.auth().removeStateDidChangeListener(handle)
self.handle = Auth.auth().addStateDidChangeListener (auth, user) in
print("Sign in state has changed.")
self.user = user
if let user = user
let anonymous = user.isAnonymous ? "anonymously " : ""
print("User signed in \(anonymous)with user ID \(user.uid). Email: \(user.email ?? "(empty)"), display name: [\(user.displayName ?? "(empty)")]")
else
print("User signed out.")
self.signIn()
如果您对更多背景感兴趣,请查看我关于使用 SwiftUI 和 Firebase 构建待办事项应用程序的系列文章:part 1(使用 SwiftUI 构建 UI)、part 2(在 Firestore 中存储数据并使用Firebase 匿名身份验证),part 3(使用 Apple 登录)
【讨论】:
以上是关于无法转换“AuthResultCallback”类型的值?的主要内容,如果未能解决你的问题,请参考以下文章
无法在 DataFlow Apache Beam 中创建通用日期转换类
AWS DynamoDB - 转换器类 - “错误请求,无法解析JSON”
类 Illuminate\Routing\Redirector 的对象无法转换为 int laravel