【Swift UI/Firebase】Authenticationでログイン状態で起動画面を切り替える方法

この記事からわかること

  • Swift UIFirebaseAuthenticationログイン状態によって起動画面切り替える方法
  • addStateDidChangeListenerメソッドcurrentUserプロパティ使い方
  • ログアウトボタン実装方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

参考文献:公式リファレンス

Firebase Authenticationでログイン状態で起動画面を切り替える方法

Firebase Authenticationを使ってログイン機能を実装した場合ユーザーがログインしていればログイン画面を表示させずにメイン画面を表示させるようにしていきます。

ロジックとしては現在のログイン状態を取得し、その値によって表示させるビューを変更させるようにします。

またログインした後のメイン画面からはログアウトできるようにもしておきます。

その前にAuthに用意されているログイン状態を識別するメソッドやプロパティを確認しておきます。

addStateDidChangeListenerメソッド

ログイン状態を取得するにはaddStateDidChangeListenerメソッドを使用します。

Auth.auth().addStateDidChangeListener { auth, user in
    if user != nil {
      // User is signed in.
    } else {
      // No user is signed in.
    }
}

currentUserプロパティ

ユーザーがログインしているかどうかはcurrentUserプロパティの値でも識別できます。ログインしていない場合はcurrentUserにはnilが格納されます。

if Auth.auth().currentUser != nil {
  // User is signed in.
} else {
  // No user is signed in.
}

Swift UIでの実装コード

今回はSwift UIを使用している場合にログイン状態によって起動する画面を変更していきます。

ポイント

ここではFirebase Authenticationの導入方法や使い方に関しては省略していますので以下記事を参考にしてください。

最初に表示させるビューを分岐

Swift UIで最初に表示されるビューを指定しているのはアプリ名App.swiftファイルの中のWindowGroup内です。


import SwiftUI
import FirebaseCore // 追加
import GoogleSignIn // 追加 ★

// 追加
class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        return true
    }
    // 追加 ★
    func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
        return GIDSignIn.sharedInstance.handle(url)
    }
}

@main
struct TestFirebaseApp: App {
    // 追加
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

上記はAuthとGoogleログインを導入している場合のコードです。ログイン状態によって起動画面を変化させるコードはWindowGroup内に記述します。

ログイン状態をチェックして分岐

currentUserプロパティにnilが格納されていればログイン画面を、ユーザー情報が格納されていればメイン画面を表示させます。

var body: some Scene {
    WindowGroup {
        if Auth.auth().currentUser != nil {
            ContentView()  // メイン画面
        } else {
            LoginView() // ログイン画面
        }
    }
}

これで画面を分岐させることができるようになりました。

ログアウトボタンの実装

続いてメイン画面(ContentView)側にログアウトできるボタンを実装しておきます。ボタンのアクションにログアウト処理と画面遷移処理を記述します。


import SwiftUI
import FirebaseAuth

struct ContentView: View {
    
    @State  var isActive:Bool = false

    var body: some View {
        NavigationView{
            VStack{
                
                NavigationLink(isActive: $isActive, 
                destination: {LoginView()}, 
                label: {EmptyView()})
                Button(action: {
                    do {
                        try Auth.auth().signOut()
                        isActive = true
                    } catch let signOutError as NSError {
                        print("Error signing out: %@", signOutError)
                    }
                }, label: {
                    Text("LogOut")
                })
            }.navigationBarBackButtonHidden(true)
        }
    }
}

戻るボタンを非表示にしておく

NavigationLinkを使用して画面遷移を実行すると上部に戻るボタンが追加されてしまうので遷移先となるLoginView側に.navigationBarBackButtonHidden(true)を付与しておきます。


import SwiftUI
import FirebaseAuth

struct LoginView: View {
    
    @State  var email:String = ""
    @State  var password:String = ""
    @State  var isActive:Bool = false
    
    var body: some View {
        NavigationView{
            
            VStack{
                
                NavigationLink(isActive: $isActive, 
                destination:{ ContentView()}, 
                label: {EmptyView()})
                
                TextField("mail address", text: $email).padding().textFieldStyle(.roundedBorder)
                TextField("password", text: $password).padding().textFieldStyle(.roundedBorder)
                
                Button(action: {
                    Auth.auth().signIn(withEmail: email, password: password) { result, error in
                        if result?.user != nil{
                            isActive = true
                        }else{
                            isActive = false
                        }
                    }
                }, label: {
                    Text("ログイン")
                }).padding()
            }.navigationBarBackButtonHidden(true)
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index