Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cause of error setting up Sign in with Apple for Firebase in Swift on iOS 13?

I have been following https://firebase.google.com/docs/auth/ios/apple and it does mention the error I am receiving re "sending the SHA256-hashed nonce as a hex string" but it doesn't offer any help to solve it and my searches haven't given me a solution which works.

My view controller code extract is


        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.
            // ...
          }
        }
      }

This section is different from the instructions on the webpage as Xcode gave an error


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

If I print the nonce immediately before


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

I get 2eNjrtagc024_pd3wfnt_PZ0N89GZ_b6_QJ3IZ_

response.nonce value is cd402f047012a2d5c129382c56ef121b53a679c0a5c5e37433bcde2967225afe

Obviously these aren't the same but I can't seem to work out what I am doing wrong.

Full error output is

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.
like image 499
ruraldev Avatar asked Nov 23 '19 19:11

ruraldev


People also ask

How do I set up login with Apple firebase?

Enable Apple as a sign-in providerAdd Firebase to your Apple project. Be sure to register your app's bundle ID when you set up your app in the Firebase console. In the Firebase console, open the Auth section. On the Sign in method tab, enable the Apple provider.

Does firebase work with iOS?

Go to the Firebase console. In the center of the project overview page, click the iOS+ icon to launch the setup workflow. If you've already added an app to your Firebase project, click Add app to display the platform options. Enter your app's bundle ID in the bundle ID field.

What does not match the SHA256 hash of the raw nonce?

The nonce in ID Token "MY CUSTOM STRING" does not match the SHA256 hash of the raw nonce "MY CUSTOM STRING" in the request. The trick to solve this error is to sha256 encode the custom string when you pass it as a nonce to the signInAsync method. This is what the full Apple Authentication Button looks like.

What is firebase in iOS Swift?

Firebase is a mobile backend-as-a-service that provides powerful features for building mobile apps. Firebase has three core services: Realtime database. User authentication.


2 Answers

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 )

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

let credential = OAuthProvider.credential( 
    withProviderID: "apple.com", IDToken: appleIdToken, accessToken: rawNonce )

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.

like image 161
jjj Avatar answered Oct 20 '22 02:10

jjj


Is it possible you are using the wrong credential method? ON the documentation it looks like the one that takes the nonce is:

 let credential = OAuthProvider.credential( withProviderID: "apple.com", IDToken: appleIdToken, rawNonce: rawNonce )

but the one you're using here takes an access token, not sure if that helps.

like image 35
ethanrj Avatar answered Oct 20 '22 02:10

ethanrj