はじめに
Firebaseを使ってログイン機能を実装している実装はUIkitを使った記事ならたくさん出てきましたがSwiftUIはあまり多くはなかったので書いてみようと思いました。
また、公式のドキュメント
(https://firebase.google.com/docs/auth/ios/start?hl=ja)
に慣れるために公式ドキュメントを用いて書いていきます。
前提条件
Firebaseのアカウント(Googleアカウントがある)
メール、パスワードでのログイン
流れ
(Firebase側の操作です)
- アプリをFirebaseに接続する(下準備)
- FirebaseSDKを初期化する
- 認証状態を判定する
- ログイン機能を実装する
- おまけ
アプリをFirebaseに接続する(下準備)
- Firebaseのトップページ (https://console.firebase.google.com/u/0/?hl=ja) に遷移
- プロジェクトを作成から順番に名前、Googleアナリティクスの順に設定
- Authentication→始めるをクリック
- メールを有効にする
- Authenticationをクリックしたところまで戻ってIOS+って書いてあるところをクリック
- AppleバンドルIDをXcodeで調べ、入力し、設定ファイルをダウンロード
(ここからXcode側の操作です)
7. ダウンロードしたGoogleService-Info.plist
ファイルを<アプリ名>App
と同じ階層に保存する(ドラッグアンドドロップでいいです)
8. macの画面上部のFileというところからAdd Pacage ...
をクリックする
9. 右上の検索欄に(https://github.com/firebase/firebase-ios-sdk)をいれ、Add Pacageを押す
補足
そもそもFirebase SDKとは?
ざっくりいうと「FirebaseをSwiftで使う上でこれだけあればなんとかなるやろ!」みたいなもの
ゲームで言うと
- スマブラのDLCがまとめて購入できるファイターパス
- ポケモンのディンカイサーフパオカミウーラのレンタルパーティ
みたいな感じです(例え下手でごめんなさい)
みたいなイメージです
AppleバンドルIDの調べ方
Xcodeの左のナビゲーション版の一番上にあるアプリ名をクリックしたら下記画像にあるIdentityを探します(Generateのところにあります)
少し消えてますが、Build Identifierのところに書かれているものがAppleバンドルIDです!
FirebaseSDKを初期化する
公式ドキュメントにはこう書かれてます
SwiftUIにはAppDeligate
がないので<アプリ名>App
のファイルに記述します。
import SwiftUI
// importを忘れずに
import FirebaseCore
@main
struct <アプリ名>App: App {
// ここから記述
init() {
FirebaseApp.configure()
}
// ここまで記述
var body: some Scene {
WindowGroup {
Login()
}
}
}
認証状態を判定する
公式ドキュメントにはこう書かれてます。
「認証状態をリッスンする」とは「ログインしてるかしてないかの判定」のことです。(小泉進次郎並感)
記述の場所は各種ViewModelですのでこの後記述していきます。
Auth.auth().addStateDidChangeListener
はFirebaseの関数で「ユーザーがログインしたりログアウトしたりしたときに、その状態の変化を通知」する役割があります
各種機能を実装する(ログイン、新規登録、ログアウト、パスワードのリセット)
ここまできたらあとはドキュメントに書かれているコードをひとつひとついい感じに書いていくだけです!
私は下記サイトを参考にしました
(https://zenn.dev/joo_hashi/articles/3e28d2f6e46674)
ログイン処理
ViewModel
import Foundation
import FirebaseAuth
class LoginViewModel: ObservableObject {
@Published var email: String = ""
@Published var password: String = ""
@Published var isAuth:Bool = false
init() {
// インスタンスが生成されたら認証情報を確認
observeAuthChanges()
}
// 認証状態を確認する
private func observeAuthChanges() {
Auth.auth().addStateDidChangeListener { [weak self] _, user in
DispatchQueue.main.async {
self?.isAuth = user != nil
}
}
}
// ログインする関数
func signIn(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { [weak self] result, error in
DispatchQueue.main.async {
if result != nil, error == nil {
self?.isAuth = true
}
}
}
}
}
View
import SwiftUI
struct Login: View {
@State var email: String = ""
@State var password: String = ""
@StateObject var loginViewModel = LoginViewModel()
var body: some View {
NavigationStack {
TextField("email", text: $email)
SecureField("password", text: $password)
NavigationLink {
SignUp().toolbar(.hidden)
} label: {
Text("会員登録へ")
}
NavigationLink {
RessetPassword()
} label: {
Text("パスワードを忘れた方")
}
Button(action: {
loginViewModel.signIn(email: email, password: password)
}) {
Text(AppConstant.login)
}
NavigationLink(
destination: Home().toolbar(.hidden),
isActive: Binding(
get: { loginViewModel.isAuth },
set: { loginViewModel.isAuth = $0 }
),
label: {
EmptyView()
})
}
}
}
}
みたいな感じで書いていきます。
新規会員登録、パスワードのリセットなどの機能も同様に公式ドキュメントに書いてある関数を使えばできます。
おまけ
Firebaseのメール、パスワードでログインする機能の主要な関数まとめ
Auth.auth().addStateDidChangeListener
ユーザーがログインしたりログアウトしたりしたときに、その状態の変化を通知
Auth.auth().signIn(withEmail: email, password: password)
サインインする関数
Auth.auth().createUser(withEmail: email, password: password)
新規会員登録
Auth.auth().sendPasswordReset(withEmail: email)
指定のメールアドレスにリセットのメールを飛ばす