I am adding a SignInWIthApple button to my app. I follow the guide from Firebase to set up it but when I run my app, I click the button , there is no user in Firebase console. And it's weird that based on the guide from Firebase, you should initialize a firebase credential like this. But Xcode reminds that OAuthProvider has no parameter of appleCredential. So I have to change appleCredential to credential.
// Initialize a Firebase credential, including the user's full name.
let credential = OAuthProvider.appleCredential(withIDToken: idTokenString,
rawNonce: nonce,
fullName: appleIDCredential.fullName)
// Sign in with Firebase.
And I paste the relevant code below. I don't know whether it's the reason.
//Mark:apple sign in button
SignInWithAppleButton(onRequest: { request in
request.requestedScopes = [.fullName, .email]
let nonce = fireAuth.randomNonceString()
fireAuth.currentNonce = nonce
request.nonce = fireAuth.sha256(nonce)
},
onCompletion: { result in
if case.failure(let failure) = result {
errorMessage = failure.localizedDescription
}
else if case.success(let success) = result {
if let appleIDCredential = success.credential as? ASAuthorizationAppleIDCredential {
guard let nonce = fireAuth.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 serialise token string from data: \(appleIDToken.debugDescription)")
return
}
// Initialize a Firebase credential
let credential = OAuthProvider.credential(withProviderID:"apple.com",
idToken: idTokenString,
rawNonce: nonce
)
// Sign in with Firebase.
Auth.auth().signIn(with: credential){(authResult,err) in
if let error = err{
print(error.localizedDescription)
return
}
}
//User successfully logged into firebase...
print("Logged In Success")
}
}
})
.frame(width:150,height:40)
class FireAuth: ObservableObject {
// static let share = FireAuth()
@State var currentNonce: String? = String()
init() {}
// Apple Sign In
func randomNonceString(length: Int = 32) -> String {
precondition(length > 0)
var randomBytes = [UInt8](repeating: 0, count: length)
let errorCode = SecRandomCopyBytes(kSecRandomDefault, randomBytes.count, &randomBytes)
if errorCode != errSecSuccess {
fatalError(
"Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)"
)
}
let charset: [Character] =
Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
let nonce = randomBytes.map { byte in
// Pick a random character from the set, wrapping around if needed.
charset[Int(byte) % charset.count]
}
return String(nonce)
}
//Hashing function using CryptoKit
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
}
}
Could you help to check it and point out which error in it? Really thanks.
I was having the same problem and I found this solution, I hope it helps you
When you authenticate for the first time, you get the name 100%. After that your app is linked to your iCloud account and you do not the name again. But you can unlink your app: As Peter Friese writes: "Unlinking your Apple ID from an app that uses Sign in with Apple Once you’ve signed in to your app, you cannot repeat the sign-in flow, which makes testing a bit of a challenge. To get back to the initial state, you need to disconnect your Apple ID from your app. Here is how:Go to https://appleid.apple.com and sign in using your Apple ID In the Security section, find Apps & Websites using Apple ID and click on Manage… You will see a pop-up dialog that shows you all apps that are connected to your Apple ID Managing apps using Apple ID. Click on the name of the app you want to disconnect The following dialog will tell you when you first started using your Apple ID with this application Click on Stop using Apple ID to disconnect this app from your Apple ID"
Now you will get the name again. You retrieve it via:
and via:
you tell Firebase to store the name into your profile. Whenever you sign-in to Firebase, Auth.auth().currentUser will now have your fullname.
Here is the source. https://github.com/firebase/firebase-ios-sdk/issues/4393#issuecomment-612193703