はじめに
Google I/O 2017で発表されたように、KotlinがAndroidの公式言語に加わったということで、mBaaS(mobile Backend as a Service)のncmb(nifty cloud mobile backend)とFirebaseを使用し、早速kotlinでAndroidプログラミングしてみました。
mBaaSはアプリ開発によく利用される汎用的な機能(ユーザー管理、データストア、プッシュ通知とか)をクラウドから提供されるサービスですが、今回は両者のユーザー認証機能について紹介していきます。
開発環境
- AndroidStudio2.3.3
- Kotlin 1.1.3
- ncmb
- firebase
※AndroidStudioにKotlinを導入する手順はこちらの記事をご参照ください。
ncmb(nifty cloud mobile backend)
アプリ新規作成
アプリを新規作成するとアプリケーションキーとクライアントキーが発行されます。
メールアドレス認証
ncmbのメールアドレス認証の流れは以下のようになっています。
1.ユーザーがメールアドレスを入力して認証をリクエストする
2.入力したメールアドレスに対して会員登録画面へのURLを含むメールが送信される
3.会員登録画面でパスワードを登録し、会員登録を行う
4.メールアドレスとパスワードでのログインが可能になる
アプリの実装
class MainActivity : AppCompatActivity(), View.OnClickListener{
// 定数
companion object Factory {
// ApplicationKey
val APP_KEY = "YOUR APP KEY" // アプリ新規作成時発行されたアプリケーションキー設定
// ClientKey
val CLIENT_KEY = "YOUR CLIENT KEY" // アプリ新規作成時発行されたクライアントキー設定
}
private var mEmailField: EditText? = null
private var mPasswordField: EditText? = null
private var loginMailAddress: EditText? = null
private var loginPassword: EditText? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//********** APIキーの設定とSDKの初期化 **********
NCMB.initialize(this.baseContext, APP_KEY, CLIENT_KEY)
// 会員登録
mEmailField = findViewById(R.id.MailAddress) as EditText
mPasswordField = findViewById(R.id.Password) as EditText
// ログイン
loginMailAddress = findViewById(R.id.login_MailAddress) as EditText
loginPassword = findViewById(R.id.login_Password) as EditText
// SIGNUPボタン
findViewById(R.id.Button)?.setOnClickListener(this)
// LOGINボタン
findViewById(R.id.login_Button)?.setOnClickListener(this)
// LOGOUTボタン
findViewById(R.id.logout_Button)?.setOnClickListener(this)
}
}
/**
* ボタンクリック時
*/
override fun onClick(v : View) {
val id = v.id
if(id == (R.id.Button)) {
// 会員登録
createAccount(mEmailField?.text.toString())
} else if(id == (R.id.login_Button)) {
// ログイン
signIn(loginMailAddress?.text.toString(), loginPassword?.text.toString())
} else if(id == (R.id.logout_Button)) {
// ログアウト
signOut()
}
}
会員登録処理
会員登録処理はSIGN UPボタン押下時に呼ばれるString型のemailを引数に持つcreateAccountメソッドで行います。
private fun createAccount(email: String) {
NCMBUser.requestAuthenticationMailInBackground(email) { e ->
if(e == null) {
println("ユーザーメール認証成功")
} else {
println("ユーザーメール認証失敗")
}
}
}
javaで書くとこんな感じになります。kotlinより冗長的な記述になっています。
NCMBUserのrequestAuthenticationMailInBackgroundメソッドは、引数にユーザーが入力したメールアドレスとDoneCallbackというインターフェースを引数にとります。ここではDoneCallbackインターフェースを実装した匿名クラスを生成して、引数に渡しています。
private void createAccount(String email) {
NCMBUser.requestAuthenticationMailInBackground(email,
new DoneCallback() {
@Override
public void done(NCMBException e) {
if (e == null) {
System.out.println("ユーザーメール認証成功");
} else if {
System.out.println("ユーザーメール認証失敗");
}
}
});
}
kotlinで記述した方にはDoneCallbackインターフェースやdone(NCMBException e)というメソッドが省略されていますが、これはSAMインターフェースによるSAM変換が行われています。
SAM(Single Abstract Method)は一つだけ抽象メソッドを持つインターフェースです。
DoneCallbackインターフェースの抽象メソッドdone(NCMBException e)は、戻り値にvoid型、引数にNCMBException型を持ちます。そのため関数リテラルの型を省略し型推論により、kotlinのようにスッキリ記述することが出来ます。
関数リテラルについてはこちらの記事を参考にさせて頂きました。
正常に会員登録が出来たら、ncmbの会員管理画面にユーザー情報が登録されます。
ログイン処理
ログイン処理はLOGINボタン押下時に呼ばれるString型のemailとString型のpasswordを引数に持つsignInメソッドで行います。signInメソッドの中でNCMBUserのloginWithMailAddressInBackgroundメソッドを呼び出せばログインします。
private fun signIn(email: String, password: String) {
NCMBUser.loginWithMailAddressInBackground(email, password) {user, e ->
if(e == null) {
println("ログイン成功")
} else {
println("ログイン失敗 :" + e.message.toString() )
}
}
}
会員登録用メールからパスワードを登録し会員登録を行った後であれば、メールアドレスとパスワードでのログインが可能になります。
ログアウト処理
ログアウト処理はログアウトボタン押下時に呼ばれる引数なしのsignOutメソッドを呼び出します。
sighOutメソッドの中でNCMBUserのlogoutInBackgroundメソッド呼び出せばログアウトします。
private fun signOut() {
NCMBUser.logoutInBackground{ e ->
if (e == null) {
println("ログアウト成功")
} else {
println("ログアウト失敗")
}
}
}
ダッシュボードの設定
メールアドレスパスワード認証を許可する場合は、ダッシュボードのアプリ設定→会員認証設定からメールアドレス/パスワード認証を許可するにチェックし保存してください。
Firebase
プロジェクト新規作成
FirebaseにGoogleアカウントでログインし、プロジェクトを新規作成します。
メール/パスワードの認証を許可する
FirebaseのAuthentication管理画面からメール/パスワードのステータスを有効にします。
アプリの実装
class MainActivity : AppCompatActivity(), View.OnClickListener {
private var mEmailField: EditText? = null
private var mPasswordField: EditText? = null
private var loginEmail: EditText? = null
private var loginPassword: EditText? = null
private var mAuth: FirebaseAuth? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ユーザー新規作成項目
mEmailField = findViewById(R.id.MailAddress) as EditText
mPasswordField = findViewById(R.id.Password) as EditText
// ログイン時項目
loginEmail = findViewById(R.id.login_MailAddress) as EditText
loginPassword = findViewById(R.id.login_Password) as EditText
// SIGN UPボタン押下時
findViewById(R.id.Button)?.setOnClickListener(this)
// LOGINボタン押下時
findViewById(R.id.login_Button)?.setOnClickListener(this)
// LOGOUTボタン押下時
findViewById(R.id.logout_Button)?.setOnClickListener(this)
// FirebaseAuthインスタンス取得
mAuth = FirebaseAuth.getInstance()
}
/**
* ボタンクリック時処理
*/
override fun onClick(v: View) {
val i = v.id
if (i == R.id.Button) {
//新規作成ボタン押下時
createAccount(mEmailField?.text.toString(), mPasswordField?.text.toString())
} else if (i == R.id.login_Button) {
// ログインボタン押下時
signIn(loginEmail?.text.toString(), loginPassword?.text.toString())
} else if (i == R.id.logout_Button) {
// ログアウトボタン押下時
signOut()
}
}
アプリレベルのbuild.gradleにFirebase Authenticationの依存関係を追加
dependencies {
(省略 )
// Firebase Authentication
compile 'com.google.firebase:firebase-auth:10.0.1' 追加
}
会員登録処理
SIGN UPボタン押下時に呼ばれるcreateAccountメソッドの中で、FirebaseインスタンスのcreateUserWithEmailAndPasswordメソッドにユーザーが入力したメールアドレス、パスワードを渡して、新しいアカウントを作成します。
private fun createAccount(email: String, password: String) {
mAuth?.createUserWithEmailAndPassword(email, password)
?.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
println("ユーザー作成成功")
sendEmailVerrification()// 確認メール送信
} else {
println("ユーザー作成失敗 :" + task.exception.toString())
}
}
}
注意点:ncmbでは会員登録時に確認用のメールが送信され、メール内のリンクをクリックしてパスワードを設定し会員登録完了になりましたが、Firebaseでは会員登録時確認メールが送信されません。
そのため、新規ユーザー作成が成功したら確認メールを送信するメソッドを作り呼び出すようにしています。
正常にユーザーが作成出来たらFirebaseの管理画面にユーザー情報が保存されます。
確認メール送信処理
新規ユーザー作成に成功したらこのメソッドを呼び出して、ユーザーに確認メールを送信します。
private fun sendEmailVerrification() {
val user = FirebaseAuth.getInstance().currentUser
user?.sendEmailVerification()
?.addOnCompleteListener(this) { task ->
if(task.isSuccessful) {
println("メール送信成功")
} else {
println("メール送信失敗 :" + task.exception.toString())
}
}
}
ログイン処理
LOGINボタン押下時に呼ばれるdignInメソッドの中で、FirebaseインスタンスのsignInWithEmailAndPasswordメソッドにユーザーが入力したメールアドレス、パスワードを引数に渡します。
private fun signIn(email: String, password: String) {
mAuth?.signInWithEmailAndPassword(email, password)
?.addOnCompleteListener(this) { task ->
if(task.isSuccessful) {
println("ログイン成功 ユーザー:" + mAuth?.currentUser.toString())
} else {
println("ログイン失敗")
}
}
}
ログウト処理
LOGOUTボタン押下時に呼ばれるsignOutメソッドで、FirebaseインスタンスのsignOutメソッドを呼んでログアウトします。
private fun signOut() {
mAuth?.signOut()
}
Firebase Analytics
Firebaseにはモバイルアプリに特化したGoogleアナリティクスの位置づけのFirebase Analyticsというツールもあり、あまり詳しく調べてませんがアクセス解析にも便利そうです。
導入手順についてはこちらの記事が分かり易かったです。
参考資料
NCMB公式ドキュメント
Firebase公式ドキュメント
http://qiita.com/RyotaMurohoshi/items/01b370f34a4bf96f5c39
http://kotlin.hatenablog.jp/entry/2012/12/10/093018