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