LoginSignup
11
7

More than 5 years have passed since last update.

Kotlin + Androidで『nifty cloud mobile backend』と『Firebase』のAuthenticationを使ってみた

Last updated at Posted at 2017-07-17

はじめに

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)

アプリ新規作成

まずはダッシュボードからアプリを新規作成します。
図1.png

スクリーンショット 2017-07-16 13.03.38.png
アプリを新規作成するとアプリケーションキーとクライアントキーが発行されます。
スクリーンショット 2017-07-16 12.52.52.png

メールアドレス認証

ncmbのメールアドレス認証の流れは以下のようになっています。

1.ユーザーがメールアドレスを入力して認証をリクエストする
2.入力したメールアドレスに対して会員登録画面へのURLを含むメールが送信される
3.会員登録画面でパスワードを登録し、会員登録を行う
4.メールアドレスとパスワードでのログインが可能になる

アプリの実装

MainActivity.kt

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メソッドで行います。

MainActivity.kt
private fun createAccount(email: String) {
        NCMBUser.requestAuthenticationMailInBackground(email) { e ->
                if(e == null) {
                    println("ユーザーメール認証成功")
                } else {
                    println("ユーザーメール認証失敗")
                }
        }
    }

javaで書くとこんな感じになります。kotlinより冗長的な記述になっています。
NCMBUserのrequestAuthenticationMailInBackgroundメソッドは、引数にユーザーが入力したメールアドレスとDoneCallbackというインターフェースを引数にとります。ここではDoneCallbackインターフェースを実装した匿名クラスを生成して、引数に渡しています。

MainActivity.java
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の会員管理画面にユーザー情報が登録されます。
スクリーンショット 2017-07-17 0.52.31.png

ログイン処理

ログイン処理はLOGINボタン押下時に呼ばれるString型のemailとString型のpasswordを引数に持つsignInメソッドで行います。signInメソッドの中でNCMBUserのloginWithMailAddressInBackgroundメソッドを呼び出せばログインします。

MainActivity.kt

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メソッド呼び出せばログアウトします。

MainActivity.kt
    private fun signOut() {
        NCMBUser.logoutInBackground{ e ->
            if (e == null) {
                println("ログアウト成功")
            } else {
                println("ログアウト失敗")
            }
        }
    }

ダッシュボードの設定

メールアドレスパスワード認証を許可する場合は、ダッシュボードのアプリ設定→会員認証設定からメールアドレス/パスワード認証を許可するにチェックし保存してください。
スクリーンショット 2017-07-16 21.25.06.png

Firebase

プロジェクト新規作成

FirebaseにGoogleアカウントでログインし、プロジェクトを新規作成します。
スクリーンショット 2017-07-17 0.35.53.png

メール/パスワードの認証を許可する

FirebaseのAuthentication管理画面からメール/パスワードのステータスを有効にします。
スクリーンショット 2017-07-17 0.46.26.png

アプリの実装

MainActivity.kt

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の依存関係を追加

build.gradle
dependencies {

     (省略 )

    // Firebase Authentication
    compile 'com.google.firebase:firebase-auth:10.0.1' 追加
}

会員登録処理

SIGN UPボタン押下時に呼ばれるcreateAccountメソッドの中で、FirebaseインスタンスのcreateUserWithEmailAndPasswordメソッドにユーザーが入力したメールアドレス、パスワードを渡して、新しいアカウントを作成します。

MainActivity.kt
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の管理画面にユーザー情報が保存されます。
スクリーンショット 2017-07-17 1.59.22.png

確認メール送信処理

新規ユーザー作成に成功したらこのメソッドを呼び出して、ユーザーに確認メールを送信します。

MainActivity.kt
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メソッドにユーザーが入力したメールアドレス、パスワードを引数に渡します。

MainActivity.kt
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メソッドを呼んでログアウトします。

MainActivity.kt
private fun signOut() {
        mAuth?.signOut()
 }

Firebase Analytics

Firebaseにはモバイルアプリに特化したGoogleアナリティクスの位置づけのFirebase Analyticsというツールもあり、あまり詳しく調べてませんがアクセス解析にも便利そうです。
導入手順についてはこちらの記事が分かり易かったです。

スクリーンショット 2017-07-17 2.12.58.png

参考資料

NCMB公式ドキュメント
Firebase公式ドキュメント
http://qiita.com/RyotaMurohoshi/items/01b370f34a4bf96f5c39
http://kotlin.hatenablog.jp/entry/2012/12/10/093018

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7