
最近では、iOSアプリの開発をするエンジニアも増えてきてますが、
それに比例してアプリの開発をサポートするソリューションも増えてきました。その中の一つとしてFirebaseというMBaaSソリューションがあります。
これはGoogleがリリースしたもので、iOSアプリ、Androidアプリに限らずWebのバックエンドの処理をサポートしてくれるツールです。
ここでは、その中の1つであるFirebase Authenticationというツールを紹介します。
このツールはユーザー、パスワードを入力するログイン実装機能をサポートしてくれます。それだけではなく、ここでは扱いませんがソーシャルログインなどGoogleアカウントでログインする実装などもできたりします。
メールアドレスの認証の場合は、以下にメールアドレスとパスワードが保存される。
そして、それ以外でgoogleやtwitterなど使いたい場合は、以下のように選択できる。
これにより認証したときに、各プロパイダの認可サーバへアクセスしてあったら、リダイレクトして認証する仕組み
まずは実装イメージをしてみます。
- SwiftUIでログイン画面(メールアドレスとパスワード)を実装する
- 入力したメールアドレスとパスワードの情報をFirebaseに渡す
- すでにアカウントがあれば認証を、なければ新規登録としてアカウント作成する
- ログイン完了画面、失敗画面を表示する
ですね。
これに則って実装していきたいと思います。
Contents
ログイン画面を実装する
まず簡単にViewにメールアドレスやパスワードの入力欄を作成します。
Firebase AuthenticationはFirebaseをcocoapodsに入れてライブラリをインストーすることで、
そのパッケージ内にFirebaseAuthが入っている。
import SwiftUI
import FirebaseAuth
struct NewLogin: View {
@State public var mail:String = ""
@State public var password:String = ""
@State public var errorMessage:String = ""
var body: some View {
VStack(spacing: 30){
// メールアドレス
TextField("メールアドレスを入力してください",text: $mail)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// パスワード
SecureField("パスワードを入力してください",text:$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// 認証
Button(
action:{
if(self.mail != ""){
self.errorMessage = "メールアドレスが入力されていません"
} else if(self.password != ""){
self.errorMessage = "パスワードが入力されていません"
} else {
// 認証する処理
}
}, label:{
Text("ログインする")
})
}
}
}
上記のように、普通にViewに入力欄を作成して、ボタンを実装し、
入力されていなかったらエラーメッセージを出して認証処理しないようになっている。
Firebase Authenticationで新規会員登録する
import SwiftUI
import FirebaseAuth
struct NewLogin: View {
@State public var mail:String = ""
@State public var password:String = ""
@State public var errorMessage:String = ""
var body: some View {
VStack(spacing: 30){
// メールアドレス
TextField("メールアドレスを入力してください",text: $mail)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// パスワード
SecureField("パスワードを入力してください",text:$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// 認証
Button(
action:{
if(self.mail == ""){
self.errorMessage = "メールアドレスが入力されていません"
} else if(self.password == ""){
self.errorMessage = "パスワードが入力されていません"
} else {
Auth.auth().createUser(withEmail: self.mail, password: self.password) { authResult, error in
print(authResult)
}
}
}, label:{
Text("新規会員登録する")
})
}
}
}
新規会員登録では、上のAuthの処理がそれにあたります。新規会員登録ボタンをクリックすると追加処理です。
Auth.auth().createUser(withEmail: self.mail, password: self.password) { authResult, error in
print(authResult)
}
上記処理が走ると成功した場合、以下のようにFirebaseにメールアドレスとパスワードの会員情報が連携されます。
Firebase Authenticationで認証する
さて先程作成したログイン情報を用いてログインしてみます。
import SwiftUI
import FirebaseAuth
struct NewLogin: View {
@State public var mail:String = ""
@State public var password:String = ""
@State public var errorMessage:String = ""
var body: some View {
VStack(spacing: 30){
// メールアドレス
TextField("メールアドレスを入力してください",text: $mail)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// パスワード
SecureField("パスワードを入力してください",text:$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// 認証
Button(
action:{
if(self.mail == ""){
self.errorMessage = "メールアドレスが入力されていません"
} else if(self.password == ""){
self.errorMessage = "パスワードが入力されていません"
} else {
Auth.auth().signIn(withEmail: self.mail, password: self.password) { authResult, error in
if authResult?.user != nil {
// ログイン成功処理
print("success")
} else {
// ログイン失敗処理
if let error = error as NSError?, let errorCode = AuthErrorCode(rawValue: error.code) {
switch errorCode {
case .invalidEmail:
self.errorMessage = "メールアドレスの形式が正しくありません"
case .userNotFound, .wrongPassword:
self.errorMessage = "メールアドレス、またはパスワードが間違っています"
case .userDisabled:
self.errorMessage = "このユーザーアカウントは無効化されています"
default:
self.errorMessage = error.domain
}
}
}
}
}
}, label:{
Text("ログインする")
})
}
}
}
先程アカウント登録で入力したメールアドレスとパスワードを入力して、
successとlogで表示されればログイン成功です!
Firebase Authenticationからアカウントの削除をする
次にアカウントの削除をしてみます。
→ よく皆さんのアプリなど使っていて削除するのは、自分がログイン状態でマイページから削除などがあるかと思います。
なので記載するコードとしては以下のようになります。
https://firebase.google.com/docs/auth/ios/manage-users?hl=ja
let user = Auth.auth().currentUser
user?.delete { error in
if let error = error {
// An error happened.
} else {
// Account deleted.
}
}
そしてログインしている状態で削除することになるので、
アカウント作成はしていると想定して、
メールアドレスとパスワード入力して「ログインする」ボタンをクリックして、
その後「アカウント削除」ボタンをクリックしてFirebaseからアカウントが削除されていることを確認します。
import SwiftUI
import FirebaseAuth
struct NewLogin: View {
@State public var mail:String = ""
@State public var password:String = ""
@State public var errorMessage:String = ""
@State public var stateLogin:Bool = false // ログイン状態
var body: some View {
VStack(spacing: 30){
// メールアドレス
TextField("メールアドレスを入力してください",text: $mail)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// パスワード
SecureField("パスワードを入力してください",text:$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// 認証
Button(
action:{
if(self.mail == ""){
self.errorMessage = "メールアドレスが入力されていません"
} else if(self.password == ""){
self.errorMessage = "パスワードが入力されていません"
} else {
Auth.auth().signIn(withEmail: self.mail, password: self.password) { authResult, error in
if authResult?.user != nil {
// ログイン成功処理
print("success")
self.stateLogin = true
} else {
// ログイン失敗処理
if let error = error as NSError?, let errorCode = AuthErrorCode(rawValue: error.code) {
switch errorCode {
case .invalidEmail:
self.errorMessage = "メールアドレスの形式が正しくありません"
case .userNotFound, .wrongPassword:
self.errorMessage = "メールアドレス、またはパスワードが間違っています"
case .userDisabled:
self.errorMessage = "このユーザーアカウントは無効化されています"
default:
self.errorMessage = error.domain
}
}
}
}
}
}, label:{
Text("ログインする")
})
// アカウント削除
Button(
action:{
let user = Auth.auth().currentUser
user?.delete { error in
if let error = error {
// An error happened.
} else {
print("削除成功")
}
}
}, label:{
Text("アカウント削除する")
})
}
}
}
Firebaseからアカウントが削除されているのが確認できると思います!
成功しました!
他のViewに行ってもログイン状態保持?
ログイン状態は別のViewに遷移しても保持されるのかを検証。
ログインしている場合は以下でcurrentUserという値がFirebaseのUIDが入るようになっている。
なので別Viewでこの値が取れるかどうかで検証。
import SwiftUI
import FirebaseAuth
struct NewLogin: View {
@State public var mail:String = ""
@State public var password:String = ""
@State public var errorMessage:String = ""
@State public var stateLogin:Bool = false // ログイン状態
var body: some View {
VStack(spacing: 30){
if(self.stateLogin){
LoginRetain()
} else {
// メールアドレス
TextField("メールアドレスを入力してください",text: $mail)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// パスワード
SecureField("パスワードを入力してください",text:$password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
// 認証
Button(
action:{
if(self.mail == ""){
self.errorMessage = "メールアドレスが入力されていません"
} else if(self.password == ""){
self.errorMessage = "パスワードが入力されていません"
} else {
Auth.auth().signIn(withEmail: self.mail, password: self.password) { authResult, error in
if authResult?.user != nil {
// ログイン成功処理
print("success")
self.stateLogin = true
} else {
// ログイン失敗処理
if let error = error as NSError?, let errorCode = AuthErrorCode(rawValue: error.code) {
switch errorCode {
case .invalidEmail:
self.errorMessage = "メールアドレスの形式が正しくありません"
case .userNotFound, .wrongPassword:
self.errorMessage = "メールアドレス、またはパスワードが間違っています"
case .userDisabled:
self.errorMessage = "このユーザーアカウントは無効化されています"
default:
self.errorMessage = error.domain
}
}
}
}
}
}, label:{
Text("ログインする")
})
}
}
}
}
struct LoginRetain:View{
var body: some View {
Text("Login完了")
Button(
action:{
let user = Auth.auth().currentUser
var _ = print(user)
}, label:{
Text("状態保持テスト")
})
}
}
Firebaseのヘルプには以下のようにありました。
''currentUser を使用することでも、現在ログインしているユーザーを取得できます。ユーザーがログインしていない場合、currentUser は nil です。''
参照
そのためLoginRetainというViewを作成して、currentUserが取得できるかどうかをログで確認します。
ログインするボタンを押してログインできると、LoginRetainが表示され、さらに状態保持テストボタンをクリックしてcurrentUserがログで取得できているかを確認します。
実行すると、ログで取得できているのが確認できるかと思います。
別Viewに遷移してもFirebase上でログイン状態の保持をしてくれていました。
ユーザーごとにUID発行
ユーザーが登録すると上のFirebase Authenticationの管理画面に情報が表示されるが、
そこでユーザーごとに個別のUIDを発行してくれる。
これはGoogleアカウントでのログインなどのソーシャルログインで実装した場合もUIDが発行されるので、
このIDを用いて様々な開発をアプリ内で行うことができる。
UIDを発行してくれるのもメリットの一つですね!
Authenticationには2種類存在する。
1つ目はカスタマイズが可能な、Firebase Authenticationそのまま。
2つ目はUIのカスタマイズができない、Firebase Authentication UI
どっちを使うかはその時々で選択する必要があるが、
アプリの独自性を出すだったりすると、カスタマイズ性の富んだ2つ目を利用するのがいい。
Googleアカウントでログインできるように実装
以下で扱ってます。 続きを見る
【SwiftUI】SwiftUIでFirebase Authenticationでプロパイダ認証を実装する(ソーシャルログイン)


