使用苹果登录firebase无法在firebase注册



我正在尝试向苹果公司注册firebase。我成功注册了苹果,但这给了我下一个错误

Optional(__C.FIRAuthErrorCode)
Optional(Error Domain=FIR
AuthErrorDomain Code=17094 "Nonce is missing in the request." UserInfo= 
{NSLocalizedDescription=Nonce is missing in the request., 
FIRAuthErrorUserInfoNameKey=ERROR_MISSING_OR_INVALID_NONCE})

这是我的代码

import UIKit
import Foundation
import AuthenticationServices
import Firebase
import CryptoKit
class firstCV: UIViewController {
   
    fileprivate var currentNonce: String?
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpView()
        
        
        
        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        
    
    }
    
    static 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 length == 0 {
                    return
                }
                
                if random < charset.count {
                    result.append(charset[Int(random)])
                    remainingLength -= 1
                }
            }
        }
        
        return result
    }
    
    @available(iOS 13.0, *)
    override 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 received, but no login request was sent.")
        }
        guard let appleIDToken = appleIDCredential.identityToken else {
          print("Unable to fetch identity token")
          return
        }
        guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
          print("Unable to serialize token string from data: (appleIDToken.debugDescription)")
          return
        }
        // Initialize a Firebase credential.
        
        let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                  idToken: idTokenString,
                                                  accessToken: nonce)
        // Sign in with Firebase.
        Auth.auth().signIn(with: credential) { (authResult, error) in
            if (error != nil) {
                
                
                
                let castedError = error! as NSError
                let firebaseError = AuthErrorCode(rawValue: castedError.code)
                
               
            // Error. If error.code == .MissingOrInvalidNonce, make sure
            // you're sending the SHA256-hashed nonce as a hex string with
            // your request to Apple.
            return
          }
          let storyboard = UIStoryboard(name: "Main", bundle: nil)
          let controller = storyboard.instantiateViewController(withIdentifier: "ageVC")
          self.present(controller, animated: true, completion: nil)
          if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ageVC") as? ageVC
          {
            self.present(vc, animated: true, completion: nil)
          }
        }
      }
    }
    @available(iOS 13.0, *)
    override func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
      // Handle error.
      print("Sign in with Apple errored: (error)")
    }
    
    @available(iOS 13, *)
    static 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
    }
    
    func setUpView(){
        
        if #available(iOS 13.0, *) {
            let appleButton = ASAuthorizationAppleIDButton(type: .default, style: .white)
             appleButton.translatesAutoresizingMaskIntoConstraints = false
            
            appleButton.addTarget(self, action: #selector(didTapAppleButton), for: .touchUpInside)
            
            view.addSubview(appleButton)
            NSLayoutConstraint.activate([appleButton.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -30),
                                         appleButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 45),
                                         appleButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -45),
                                         appleButton.heightAnchor.constraint(equalToConstant: 40)])
            
            view.bringSubviewToFront(appleButton)
            
        } else {
            // Fallback on earlier versions
        }
    }
    
    
    
    @available(iOS 13.0, *)
    @objc
    func didTapAppleButton(){
        let nonce = firstCV.randomNonceString()
        currentNonce = nonce
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.email]
        request.nonce = firstCV.sha256(nonce)
        let controller = ASAuthorizationController(authorizationRequests: [request])
        
        controller.delegate = self
        controller.presentationContextProvider = self
        controller.performRequests()
    }
}

extension UIViewController: ASAuthorizationControllerDelegate{
    
    @available(iOS 13.0, *)
    public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authrezation: ASAuthorization){
    }
    
    @available(iOS 13.0, *)
    public func authorizationController(controller: ASAuthorizationController, didCompleteWithError: Error){
        
    }
    
}
extension UIViewController: ASAuthorizationControllerPresentationContextProviding{
    @available(iOS 13.0, *)
    public func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
         return view.window!
    }
}

在OAuthCredential初始化期间,您传递的是访问令牌,而不是原始nonce:

let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                              idToken: idTokenString,
                                              rawNonce: nonce)
import AuthenticationServices
import CryptoKit
import FirebaseFirestore
import CommonCrypto
 fileprivate var currentNonce: String?
/* guard let nonce = currentNonce else {
            fatalError("Invalid state: A login callback was received, but no login request was sent.")
        }*/
let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                  idToken: idTokenString,
                                                  accessToken: currentNonce?.sha256()
 @objc func signInButtonPressed() {
    if #available(iOS 13.0, *) {
        //let nonce = randomNonceString()
        //currentNonce = nonce
        let appleIDProvider = ASAuthorizationAppleIDProvider()
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
        request.nonce = currentNonce?.sha256()
        
        let authorizationController =   ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    } else {
        // Fallback on earlier versions
    }
    
    
}
extension String {
func sha256() -> String {
    if let stringData = self.data(using: String.Encoding.utf8) {
        return hexStringFromData(input: digest(input: stringData as NSData))
    }
    return ""
}
private func digest(input : NSData) -> NSData {
    let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
    var hash = [UInt8](repeating: 0, count: digestLength)
    CC_SHA256(input.bytes, UInt32(input.length), &hash)
    return NSData(bytes: hash, length: digestLength)
}
private func hexStringFromData(input: NSData) -> String {
    var bytes = [UInt8](repeating: 0, count: input.length)
    input.getBytes(&bytes, length: input.length)
    var hexString = ""
    for byte in bytes {
        hexString += String(format:"%02x", UInt8(byte))
    }
    return hexString
}
}

最新更新