Firebase IT アプリ開発

Firebase AuthenticationでAppleログイン実装する

ここではFirebase AuthenticationでAppleによるサインイン実装について話したいと思います。

Firebase AuthenticationでAppleログインを有効にする

まずFirebaseの管理画面にアクセスする。
そしてAuthenticationのSign-in methodにアクセスし、以下赤枠の新しいプロパイダを追加をクリック。

そして赤枠のAppleをクリック

有効にするをオンにして保存する

以下のようにAppleログインが有効化されました。

Xcode上でappleサインイン機能を追加する

▼ 赤枠のSignIn & Capabilitiesを選択する

▼ 赤枠の+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)
    }

}

-Firebase, IT, アプリ開発
-, ,

© 2024 Yosshi Labo. Powered by AFFINGER5