Firebaseど素人だったので、Firebase学習の為に公式ドキュメントを見て、学びをサンプルアプリという形でアウトプットしました。
まずはAuthentication
(認証)に挑戦!
作ったサンプルアプリのデモ
現在使用中のユーザーメールアドレスがラベルに表示されるアプリです。
・メールアドレスとパスワードを使った新規登録(サインアップ)
・登録済みのアカウントの認証(サインイン)
・サインアウト
・匿名認証
この機能の実装を行いました。
まずはFirebaseに登録
Firebase公式ドキュメントに沿って、Firebase登録とFirebase SDKをアプリに追加する。
Firebase を iOS プロジェクトに追加する
アプリ内でFirebaseの初期化を行う
AppDelegate.swiftにFirebaseをインポート
import Firebase
didFinishLaunchingWithOptions
内でFirebaseApp.configure()
を宣言
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
return true
}
使用するログインプロバイダのステータスを変更する
今回はメール/パスワード認証と匿名認証をログインに使用するので、Firebaseに登録したアプリのプロジェクト内Authentication
のSign-in method
で
メール/パスワード
匿名
こちらの二つのステータスを有効に変更します。
ViewControllerにFirebaseをインポート
作成を進めるファイルにもFirebaseをインポートする。
import Firebase
メール/パスワード認証
新規登録
新規登録にはcreateUser(withEmail:, password:, completion:)
を使用します。
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("登録に失敗しました:" ,error!.localizedDescription)
return
}
print("登録に成功しました", user.email!)
}
サインイン
サインインには、signIn(withEmail:, password:, completion:)
を使用します。
Auth.auth().signIn(withEmail: email, password: password) { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("サインインに失敗しました:" ,error!.localizedDescription)
return
}
print("サインインに成功しました", user.email!)
}
匿名ログイン
匿名ログインにはAuth.auth().signInAnonymously(completion:)
を使います。
Auth.auth().signInAnonymously { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("匿名サインインに失敗しました:" ,error!.localizedDescription)
return
}
print("匿名サインインに成功しました", user.uid)
}
サインアウト
signOut()
を呼ぶだけです。
do {
try Auth.auth().signOut()
} catch let signOutError as NSError {
print("サインアウトに失敗しました:", signOutError)
}
現在ログインしているユーザーを取得する
現在ログインしているユーザーを取得するには、Auth オブジェクトでリスナーを設定することをおすすめします。
とのことで、リスナーを設定してみました。
1.AuthStateDidChangeListenerHandle
をグローバル変数として定義
var authHandle: AuthStateDidChangeListenerHandle?
2.viewWillAppear
でaddStateDidChangeListener(listener:)
をアタッチ
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
authHandle = Auth.auth().addStateDidChangeListener({ (auth, user) in
//ログイン状態が変更された時の処理を書く
})
}
viewWillAppear
でアタッチしたこのリスナーは、ユーザーのログイン状態が変更される度に呼び出されます。
変更される度に実行したい処理をここに書きます。
とても便利ですね。
ログインされてるなら別ページに遷移、ログイン無しなら登録ページを表示などの使い分けにも有効そうです。
その他の方法では、currentUser
でログインユーザーの状態も取得出来るようです。
currentUser を使用することでも、現在ログインしているユーザーを取得できます。ユーザーがログインしていない場合、currentUser は nil です。
3.viewWillDisappear
でリスナーを切り離します。
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
Auth.auth().removeStateDidChangeListener(authHandle!)
}
まとめ
Firebaseの公式ドキュメントはとても充実しており、日本語ページもあるので簡単にここまでは進めれました。
もっとしっかり公式ドキュメントを読み、理解を深めていきたいと思います。
何か間違いがありましたら、優しく指摘していただけると幸いです🙇♂️
参考
iOS で Firebase Authentication を使ってみる
サンプリアプリのコード全体
import UIKit
import Firebase
class AuthViewController: UIViewController {
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var currentUserEmailLabel: UILabel!
@IBOutlet weak var signUpButton: UIButton!
@IBOutlet weak var signInButton: UIButton!
var authHandle: AuthStateDidChangeListenerHandle?
override func viewDidLoad() {
super.viewDidLoad()
signUpButton.layer.cornerRadius = 22
signInButton.layer.cornerRadius = 22
emailTextField.delegate = self
passwordTextField.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
authHandle = Auth.auth().addStateDidChangeListener({ (auth, user) in
if let currentUser = user {
//もし、ユーザーが匿名で利用していたら
if currentUser.isAnonymous {
self.currentUserEmailLabel.text = "匿名で利用中"
} else {
self.currentUserEmailLabel.text = currentUser.email
}
} else {
//ログインをしていない場合
self.currentUserEmailLabel.text = "現在ログイン中のユーザーはいません"
}
})
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
Auth.auth().removeStateDidChangeListener(authHandle!)
}
// MARK: - Button Actions
//サインアウト
@IBAction func didTapSignOut(_ sender: UIBarButtonItem) {
do {
try Auth.auth().signOut()
} catch let signOutError as NSError {
print("サインアウトに失敗しました:", signOutError)
}
}
//サインアップ
@IBAction func didTapSignUp(_ sender: UIButton) {
if let email = emailTextField.text, let password = passwordTextField.text {
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("登録に失敗しました:" ,error!.localizedDescription)
return
}
print("登録に成功しました", user.email!)
}
}
}
//サインイン
@IBAction func didTapSignIn(_ sender: UIButton) {
if let email = emailTextField.text, let password = passwordTextField.text {
Auth.auth().signIn(withEmail: email, password: password) { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("サインインに失敗しました:" ,error!.localizedDescription)
return
}
print("サインインに成功しました", user.email!)
}
}
}
//匿名サインイン
@IBAction func didTapSignInAnonymously(_ sender: UIButton) {
Auth.auth().signInAnonymously { (authResult, error) in
guard let user = authResult?.user, error == nil else {
print("匿名サインインに失敗しました:" ,error!.localizedDescription)
return
}
print("匿名サインインに成功しました", user.uid)
}
}
}
// MARK: - TextField Delegate Methods
extension LoginViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}