ここではFirebase AuthenticationでAppleによるサインイン実装について話したいと思います。
Firebase AuthenticationでAppleログインを有効にする
まずFirebaseの管理画面にアクセスする。
そしてAuthenticationのSign-in methodにアクセスし、以下赤枠の新しいプロパイダを追加をクリック。
Xcode上でappleサインイン機能を追加する
▼ 赤枠のSignIn & Capabilitiesを選択する
▼ Sign in with Appleを選択してダブルクリックする
実装
import SwiftUI import Firebase @main struct SignInAppleApp: App { init() { FirebaseApp.configure() } var body: some Scene { WindowGroup { ContentView() } } }
import SwiftUI import CryptoKit import FirebaseAuth import AuthenticationServices struct ContentView: View { @State var currentNonce:String? //Hashing function using CryptoKit 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() return hashString } private func randomNonceString(length: Int = 32) -> String { precondition(length > 0) let charset: Array= 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 } var body: some View { SignInWithAppleButton( //Request onRequest: { request in let nonce = randomNonceString() currentNonce = nonce request.requestedScopes = [.fullName, .email] request.nonce = sha256(nonce) }, //Completion 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("\(String(describing: Auth.auth().currentUser?.uid))") default: break } default: break } } ).frame(width: 280, height: 45, alignment: .center) } }