微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法将 Apple 登录连接到 Firebase

如何解决无法将 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!
    }
}
,

使用 FirebaseUI 更容易实现登录 Apple,我让 Auth 工作并绕过了预先构建的欢迎屏幕:

import Foundation
import UIKit
import AuthenticationServices
import FirebaseAuth
import Firebase
import FirebaseFirestore
import CryptoKit
import FirebaseUI

class LoginPopupViewController: UIViewController,ASAuthorizationControllerDelegate,FUIAuthDelegate {
    
    @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() {
                if let authUI = FUIAuth.defaultAuthUI() {
                    authUI.providers = [FUIOAuth.appleAuthProvider()]
                    authUI.delegate = self
                    authUI.signIn(withProviderUI: FUIOAuth.appleAuthProvider(),presenting: self,defaultValue: nil)
//                    let authViewController = authUI.authViewController()
//                    self.present(authViewController,animated: true)
    }
    }
    
    @objc(authUI:didSignInWithAuthDataResult:error:) func authUI(_ authUI: FUIAuth,didSignInWith authDataResult: AuthDataResult?,error: Error?) {
        dismiss(animated: true,completion: nil)
        if let user = authDataResult?.user {
            print("Nice! You've signed in as \(user.uid). Your email is: \(user.email ?? "") ")
        }
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。