swift - 无法将 Sign In with Apple 连接到 Firebase
问题描述
当我将 Sign In with Apple 连接到 Firebase 时,会出现一条错误消息“无法将“LoginPopupViewController”类型的值分配给“ASAuthorizationControllerPresentationContextProviding?” 它不会显示任何已登录 Firebase 控制台的用户。
我遵循了本教程的第二部分:https ://www.youtube.com/watch?v=BxQsdhglZtE
import Foundation
import UIKit
import AuthenticationServices
import FirebaseAuth
import Firebase
import FirebaseFirestore
import CryptoKit
class LoginPopupViewController: UIViewController, ASAuthorizationControllerDelegate {
@IBAction func doneBtn(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
setupSignInButton()
}
func setupSignInButton() {
let button = ASAuthorizationAppleIDButton(type: .signIn, style: .white)
button.addTarget(self, action: #selector(handleSignInWithAppleTapped), for: .touchUpInside)
button.frame.size = CGSize(width: 300.0, height: 40.0)
button.center = view.center
view.addSubview(button)
}
@objc func handleSignInWithAppleTapped() {
performSignIn()
}
func performSignIn() {
let request = createAppleIDRequest()
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
func createAppleIDRequest() -> ASAuthorizationOpenIDRequest {
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
let nonce = randomNonceString()
request.nonce = sha256(nonce)
currentNonce = nonce
return request
}
}
extension ViewController: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
guard let nonce = currentNonce else {
fatalError("Invalid state: A login callback was recieved, but no login request was sent")
}
guard let appleIDToken = appleIDCredential.identityToken else {
print("Unable to fetch identify token")
return
}
guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
return
}
let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce)
Auth.auth().signIn(with: credential) { (authDataResult, error) in
if let user = authDataResult?.user {
print("Nice! You're now signed in as \(user.uid), email: \(user.email ?? "unknown")")
}
}
}
}
}
extension ViewController: ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return self.view.window!
}
}
// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
private func randomNonceString(length: Int = 32) -> String {
precondition(length > 0)
let charset: Array<Character> =
Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
var result = ""
var remainingLength = length
while remainingLength > 0 {
let randoms: [UInt8] = (0 ..< 16).map { _ in
var random: UInt8 = 0
let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
if errorCode != errSecSuccess {
fatalError("Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)")
}
return random
}
randoms.forEach { random in
if remainingLength == 0 {
return
}
if random < charset.count {
result.append(charset[Int(random)])
remainingLength -= 1
}
}
}
return result
}
// Unhashed nonce.
fileprivate var currentNonce: String?
@available(iOS 13, *)
private func sha256(_ input: String) -> String {
let inputData = Data(input.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap {
return String(format: "%02x", $0)
}.joined()
return hashString
}
解决方案
你需要LoginPopupViewController
符合ASAuthorizationControllerPresentationContextProviding
extension LoginPopupViewController: ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return self.view.window!
}
}
推荐阅读
- android - Android Studio 未显示设计预览但应用程序正在运行
- javascript - 如何在 javascript 函数中使用“get_template_directory_uri”
- windows - 错误代码 8007203c 是什么意思?在 Windows 活动目录中?
- javascript - 如何在 vue 中的各个组件之间共享数据
- python - Python,用逗号分割字符串,引号内除外,忽略空格
- c# - 如何访问 Linq 中“付费”类中的 PayTime 字段
- html - 如何使一个按钮居中而不考虑另一个在 div 内内联显示的标签
- laravel - laravel 中的多对多关系查询
- mongodb - MongoDB耗尽分片但平衡器没有运行?(removeShard 耗时太长)
- python - 在 Python 2.7 中的 dict 中查找值