在 iOS 13 上的 Swift 中为 Firebase 设置登录 Apple 时出错的原因?

rur*_*dev 8 ios firebase swift sign-in-with-apple

我一直在关注https://firebase.google.com/docs/auth/ios/apple并且它确实提到了我收到的错误“将 SHA256 哈希随机数作为十六进制字符串发送”,但它没有提供任何帮助解决它,我的搜索没有给我一个有效的解决方案。

我的视图控制器代码摘录是


        fileprivate var currentNonce: String?

        @objc @available(iOS 13, *)
        func startSignInWithAppleFlow() {
          let nonce = randomNonceString()
          currentNonce = nonce
          let appleIDProvider = ASAuthorizationAppleIDProvider()
          let request = appleIDProvider.createRequest()
          request.requestedScopes = [.fullName, .email]
          request.nonce = sha256(nonce)
            print(request.nonce)

          let authorizationController = ASAuthorizationController(authorizationRequests: [request])
          authorizationController.delegate = self
          authorizationController.presentationContextProvider = self
          authorizationController.performRequests()
        }
        @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()
            print(hashString)
          return hashString
        }
    }
    @available(iOS 13.0, *)
    extension LoginViewController: 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 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.
            print(nonce)
            let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                      idToken: idTokenString,
                                                      accessToken: nonce)

            print(credential)
          // Sign in with Firebase.
          Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
            if (error != nil) {
              // Error. If error.code == .MissingOrInvalidNonce, make sure
              // you're sending the SHA256-hashed nonce as a hex string with
              // your request to Apple.
                print(authResult)
                print(error!)
                print(error!.localizedDescription)
              return
            }
            // User is signed in to Firebase with Apple.
            // ...
          }
        }
      }

Run Code Online (Sandbox Code Playgroud)

此部分与网页上的说明不同,因为 Xcode 给出了错误


    let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                      idToken: idTokenString,
                                                      accessToken: nonce)

Run Code Online (Sandbox Code Playgroud)

如果我之前打印 nonce


    let credential = OAuthProvider.credential(withProviderID: "apple.com",
                                                      idToken: idTokenString,
                                                      accessToken: nonce)

Run Code Online (Sandbox Code Playgroud)

我得到 2eNjrtagc024_pd3wfnt_PZ0N89GZ_b6_QJ3IZ_

response.nonce 值为 cd402f047012a2d5c129382c56ef121b53a679c0a5c5e37433bcde2967225afe

显然这些不一样,但我似乎无法弄清楚我做错了什么。

完整的错误输出是

Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={NSUnderlyingError=0x60000388a820 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={
    code = 400;
    errors =     (
                {
            domain = global;
            message = "MISSING_OR_INVALID_NONCE : Nonce is missing in the request.";
            reason = invalid;
        }
    );
    message = "MISSING_OR_INVALID_NONCE : Nonce is missing in the request.";
}}}, FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR, error_name=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information.}
An internal error has occurred, print and inspect the error details for more information.
Run Code Online (Sandbox Code Playgroud)

小智 18

I ran into the same error.

Solution: Just run

pod update

Explanation:

The problem is as @ethanrj says. The documentation says to do

let credential = OAuthProvider.credential( 
    withProviderID: "apple.com", IDToken: appleIdToken, rawNonce: rawNonce )
Run Code Online (Sandbox Code Playgroud)

but this gives an error and Xcode will suggest the following (rawNonce -> accessToken):

let credential = OAuthProvider.credential( 
    withProviderID: "apple.com", IDToken: appleIdToken, accessToken: rawNonce )
Run Code Online (Sandbox Code Playgroud)

This is because pod install will install FirebaseAuth 6.12 by default, when you really need 6.13 since the new function signature is only available there. You can view the source here (https://github.com/firebase/firebase-ios-sdk/blob/master/Firebase/Auth/Source/AuthProvider/OAuth/FIROAuthProvider.m).

  • 非常感谢,解决了,我自己应该想到的!有效的最终结果 let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce, accessToken: nil) (2认同)