I've implemented a Sign In With Apple as the front end, and Firebase as the backend. The objective is that the user would sign in, and the terminal would give the user's name and email. For some reason, it isn't working. Please take a look and tell me what I am missing to make it do what my goal is.
import SwiftUI
import Firebase
import AuthenticationServices
import FirebaseAuth
import CryptoKit
struct LoginView: View {
@State private var isLoginMode = false
@State private var email = ""
@State private var password = ""
@State private var address = ""
@State private var resultOfAuth = ""
@EnvironmentObject var userAuth: UserAuth
@State var currentnonce: String?
// 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: [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
}
private func sha256(_ input: String) -> String {
let inputData = Data(input.utf8)
let hashedData = SHA256.hash(data: inputData)
let hashString = hashedData.compactMap {
String(format: "%02x", $0)
}.joined()
return hashString
}
var body: some View {
NavigationView {
SignInWithAppleButton(
onRequest: { request in
let nonce = randomNonceString()
currentnonce = nonce
request.requestedScopes = [.fullName, .email]
request.nonce = sha256(nonce)
let resultOfAuth = request.requestedScopes
},
onCompletion: { result in
switch result {
case .success(let authResults):
switch authResults.credential {
case let appleIDCredential 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 {
fatalError("Invalid state: A login callback was received, but no login request was sent.")
}
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) { (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(error?.localizedDescription as Any)
return
}
print("signed in")
print(resultOfAuth)
self.userAuth.login()
NavigationLink {
HomeView()
} label: {
Text("Done")
}
}
print("\(String(describing: Auth.auth().currentUser?.uid))")
default:
break
}
default:
break
}
}
)
.frame(width: 200, height: 45, alignment: .center)
}
}
```