13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firebaseのサーバーレスアプリ開発について(Android編)

Posted at

Firebaseサーバーレスアプリのニーズ

2~3年前からサーバーレスのアプリ開発(Android/iOS)が増えています。
特にFirebaseを使っているスタートアップをよく見かけます。

アプリの競争が激しい中、今はいいアプリを作るだけで売れる時代は終わっているかも知りません。
特に資金力の弱いスタトアップだと限られた資金で短期間に成果をあげることは難しいでしょう
資金調達の為にもより早くアプリを見せないといけないです。
そういったニーズの答えがFirebaseのサービスだと思います。

Firebaseサーバーレスのメリット&デメリット

メリット&デメリットはあくまで私の個人意見です。
以下の内容以外にもいっぱいあると思います。

メリット

  • サーバー開発期間がゼロ
  • サーバー管理が不要で開発に集中できる
  • 無料枠でも結構使える
  • Firestoreだとほぼリアルタイムで更新するのでチャット機能も簡単に実現できる

デメリット

その他

Firebaseサーバーレスの実装サンプル

本投稿ではサーバーレスの実装がどれだけ簡単にできるかをコードを中心に伝えたいと思います。
導入方法については次回に紹介します。

1.Firebase Authentication

会員登録とログイン関係の全ての機能を提供しています。
サーポートする認証方式は以下の画像を参考にしてください。
FirebaseでサーポートしてないLINEなどの認証は別の方法で実装ができます。
それについては次回に紹介します。

サーポートする認証方式は色々ありますが、
本投稿では「メール/パスワード」の認証方式だけをkotlinで書いて見ました。

  • 会員登録、プロフィール変更、パスワード変更、ログイン、ログアウト、退会
a.会員登録
会員登録
    fun signup() {
        val auth = FirebaseAuth.getInstance()
        val email = "test@bizreach.co.jp"
        val password = "12345678"
        auth.createUserWithEmailAndPassword(email, password)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
会員登録後のAuthentication管理画面
b.プロフィール変更
プロフィール変更
    fun changeProfile() {
        val auth = FirebaseAuth.getInstance()
        val user = auth.currentUser ?: return

        val name = "山田"
        val profileUrl = "https://example.com/jane-q-user/profile.jpg"
        val profile = UserProfileChangeRequest.Builder()
            .setDisplayName(name)
            .setPhotoUri(Uri.parse(profileUrl))
            .build()
        user.updateProfile(profile)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
c.パスワード変更
パスワード変更
    fun changePassword() {
        val auth = FirebaseAuth.getInstance()
        val user = auth.currentUser ?: return
        val newPassword = "abcdefgh"
        user.updatePassword(newPassword)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
d.ログイン
ログイン
    fun login() {
        val auth = FirebaseAuth.getInstance()
        val email = "test@bizreach.co.jp"
        val password = "abcdefgh"
        auth.signInWithEmailAndPassword(email, password)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
e.ログアウト
ログアウト
    fun logout() {
        FirebaseAuth.getInstance().signOut()
    }
f.退会
退会
    fun withdrawal() {
        val auth = FirebaseAuth.getInstance()
        val user = auth.currentUser ?: return
        user.delete()
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
退会後のAuthentication管理画面

2.Cloud Firestore

NoSQLデータベースで、データの保存・変更・削除などの機能が簡単に使えます。
サンプルコードではToDo一覧、ToDo詳細機能をベースにデータを構成して実装して見ました。

a.ToDo登録
ToDo登録
    data class Todo(val title: String, val done: Boolean = false, val createdAt: Timestamp = Timestamp(Date()))

    fun addTodo() {
        val db = FirebaseFirestore.getInstance()
        val col = db.collection("todo_list")

        col.add(Todo("todo1"))
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }

        col.add(Todo("todo2"))
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
ToDo登録後のFirestore管理画面
b.ToDo編集
ToDo編集
    fun changeToDone() {
        val db = FirebaseFirestore.getInstance()
        val doc = db.collection("todo_list")
            .document("Hi2mlwN3lguMmfu76ZqX")

        doc.update("done", true)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
ToDo編集後のFirestore管理画面
c.ToDoの一覧取得
ToDoの一覧取得
    fun getTodoList() {
        val db = FirebaseFirestore.getInstance()
        db.collection("todo_list")
            .get()
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result ->
                /*成功*/
                result?.forEach {
                    val title = it["title"] as String
                    val done = it["done"] as Boolean
                    val createdAt = it["createdAt"] as Timestamp
                    val todo = Todo(title, done, createdAt)
                    Log.d("TAG", "todo_list: documentId=${it.id} todo=$todo")
                }
            }
    }
---- logcat
//todo_list: documentId=1aPGHKce0Fn4Osu65ioW todo=Todo(title=todo2, done=false, createdAt=Timestamp(seconds=1573460794, nanoseconds=820000000))
//todo_list: documentId=Hi2mlwN3lguMmfu76ZqX todo=Todo(title=todo1, done=true, createdAt=Timestamp(seconds=1573460794, nanoseconds=801000000))

d.ToDo削除
ToDo削除
    fun removeTodo() {
        val db = FirebaseFirestore.getInstance()
        val doc = db.collection("todo_list")
            .document("Hi2mlwN3lguMmfu76ZqX")

        doc.delete()
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
ToDo削除後のFirestore管理画面

3.Cloud Storage

ファイルの保存、変更、削除、URL参照ができます。
例えば会員のプロフィール写真などを保存して画面に表示する際に使います。
※内部的にはAWSのS3を使っています。

a.プロフィール画像のアップロード
プロフィール画像のアップロード
    fun uploadProfile() {
        val storage = FirebaseStorage.getInstance()
        val profileRef = storage.reference.child("images/profile.jpg")

        val bitmap = BitmapFactory.decodeResource(resources, R.drawable.profile)
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
        val data = baos.toByteArray()

        profileRef.putBytes(data)
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
プロフィール画像のアップロード後のStorage管理画面
b.プロフィール画像URLの取得
プロフィール画像URLの取得
    fun getProfileUrl() {
        val storage = FirebaseStorage.getInstance()
        val profileRef = storage.reference.child("images/profile.jpg")
        profileRef.downloadUrl
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result ->
                /*成功*/
                Log.d("TAG", "profileUrl = $result")
            }
    }
----logcat
profileUrl = https://firebasestorage.googleapis.com/v0/b/fir-serverlessdemo.appspot.com/o/images%2Fprofile.jpg?alt=media&token=8bbb1678-76a7-470f-8773-9f3d8d8363f4
d.プロフィール画像の削除
プロフィール画像の削除
    fun deleteProfile() {
        val storage = FirebaseStorage.getInstance()
        val profileRef = storage.reference.child("images/profile.jpg")
        profileRef.delete()
            .addOnFailureListener { exception -> /* 失敗 */ }
            .addOnSuccessListener { result -> /*成功*/ }
    }
プロフィール画像の削除後のStorage管理画面

まとめ

Firebaseを使えば認証管理、DB管理、ファイル管理がどれだけ簡単にできるか理解頂けたと思います。

伝統的なネイティブアプリの開発方法がだんだん変わっています。
昔の開発では3人(インフラエンジニア/サーバーサイドエンジニア/フロントエンジニア)でやってたのが
今はだった一人でできる時代になりました。
Firebaseを使えば質の高いアプリ(Android/iOS/Web)をたった一人で開発することができます。

以前は物理サーバーを立ててから開発することが普通でしたが、
現在ではクラウドサービス(AWS、AZUL、GCP...)を使うのが当たり前のようになっています。
それと同じ様にネイティブアプリの開発でもサーバーレスのアプリ開発が広がり、
当たり前のような時代になるかも知りません。

13
9
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
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?