🍡

SwiftUI + FirebaseUIのセットアップをしたときのメモ

2022/07/20に公開

はじめに

SwiftUIとFirebaseUIを利用したアプリの開発をはじめました。これはそのときのセットアップのメモです。

Firebase

Swift Package Managerを利用してFirebaseの導入手順を実施します。

https://firebase.google.com/docs/ios/setup?hl=ja

Firebase UI

パッケージの追加

Firebaseと同様にSwift Package Managerを利用してFirebaseUIのパッケージを追加します。パッケージのURLには以下を指定します。

https://github.com/firebase/FirebaseUI-iOS.git

このとき、パッケージのバージョンが最新でない場合があり、私の場合は最新のバージョンを手動で指定しました。最新のバージョンはreleasesのページから確認します。

https://github.com/firebase/FirebaseUI-iOS/releases

URL Schemesの設定

TARGETS > Info > URL Typesを追加してURL SchemesGoogleService-Info.plistREVERSED_CLIENT_IDを指定します。

https://ios-docs.dev/your-app-is-missing-support/

この設定をしていないと、Your app is missing support for the following URL schemesというエラーメッセージが表示されます。

Swiftで認証を制御

以下の記事のコードをコピーします。この記事のおかげでFirebaseUIを動作させることができました。

https://zenn.dev/yorifuji/articles/swiftui-firebaseui

ライブラリのアップデートの影響でimport文を一部修正する必要があり、以下のようにしました。

FirebaseUIView.swift
import SwiftUI
import FirebaseAuthUI
import FirebaseEmailAuthUI
import FirebaseGoogleAuthUI

struct FirebaseUIView: UIViewControllerRepresentable {
    typealias UIViewControllerType = UINavigationController

    class Coordinator: NSObject, FUIAuthDelegate {
        let parent: FirebaseUIView
        init(_ parent: FirebaseUIView) {
            self.parent = parent
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UINavigationController {
        let authUI = FUIAuth.defaultAuthUI()!
        let providers: [FUIAuthProvider] = [
            FUIEmailAuth(),
            FUIGoogleAuth(authUI: authUI),
        ]
        authUI.providers = providers
        authUI.delegate = context.coordinator
        return authUI.authViewController()
    }

    func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {

    }
}
FirebaseAuthStateObserver.swift
import Firebase

class FirebaseAuthStateObserver: ObservableObject {
    @Published var isSignin: Bool = false
    private var listener: AuthStateDidChangeListenerHandle!

    init() {
        listener = Auth.auth().addStateDidChangeListener { (auth, user) in
            if let _ = user {
                print("sign-in")
                self.isSignin = true
            } else {
                print("sign-out")
                self.isSignin = false
            }
        }
    }

    deinit {
        Auth.auth().removeStateDidChangeListener(listener)
    }

}
ContentView.swift
import SwiftUI
import Firebase

struct ContentView: View {
    @ObservedObject private var authState = FirebaseAuthStateObserver()
    @State var isShowSheet = false

    var body: some View {
        VStack {
            if authState.isSignin {
                Text("You are logined.")
                    .padding()
                Button("logout") {
                    try! Auth.auth().signOut()
                }
            }
            else {
                Text("You are not logged in.")
                    .padding()
                Button("login") {
                    isShowSheet.toggle()
                }
            }
        }
        .sheet(isPresented: $isShowSheet, content: {
            FirebaseUIView()
        })
    }
}

おわりに

このメモでは途中の手順で省略している部分も多いのですが、以下の記事が丁寧に解説されていました。

https://qiita.com/From_F/items/5888c548a9a41232509f

FirebaseUIのおかげでユーザー認証の画面を簡単に用意することができました。Eメールとパスワードの認証の画面は最初にメールアドレスのみを入力する画面が開くので少し違和感があったのですが、Eメールが登録済みかのチェックの画面でもあるので、それなら仕方ないかと思いました。

ひとまず動作させることができたので、SwiftUIとFirebaseUIを利用して開発を進めていきたいと思います。

Discussion

ログインするとコメントできます