01 NOTEゼロワンノートは、転職・独立したい人のサービス開発・転職・副業・起業を応援するサイトです。

Firebase Firestoreを使ってiOSアプリのデータを管理する方法

iOSアプリ開発

アプリを作る・サービスを立ち上げるといったとき、ほとんどの場合はDBやサーバーなどを必要とすると思います。DBやサーバーを用意するといったときAWS, Google Cloud Platform, VPS, Firebase, Herokuといったインフラサービスを使うと思います。

今回は、その中でもFirebase Firestoreを使ってデータを保存する方法を紹介していきます。

Firebaseとは?

Firebaseは、Googleが提供するGoogle Cloud Platformというインフラサービス上で動いているアプリ開発向けのバックエンドサービスです。
以下のような機能を提供している
  • プッシュ通知
  • データベース
  • ABテスト
  • サーバーレス
  • 認証機能
  • etc

Firebaseプロジェクトの作成方法はこちらで紹介しているので、参考にしてみてください。

Firebase Firestoreとは?

Firebase Firestoreは、Firebaseが提供するデータベース機能です。NoSQLと呼ばれるデータベースで、従来のデータベースの設計手法を変えることにより、大容量、低レイテンシー、柔軟なモデルを実現したものです。NoSQLの呼ばれる代表的なものに、Redis、Cassandra、MongoDBなどが挙げられます。

Realtime Databaseとの違い

Realtime Databaseは、Firestoreの前身となるNoSQLデータベースです。Firestoreでは、Realtime Databaseよりもより効率的にデータにアクセスができ、より柔軟なクエリーを書くことができるようになっています。また、オフラインサポートについてもWebをサポートしていてより幅広く使うことができるようになっています。

Firestore iOSの導入方法

iOSアプリにFirestoreを導入するには、CocoaPodsを利用するのをおすすめします。Podfileに以下の行を追加してinstallしましょう。

    pod 'Firebase/Core'
    pod 'Firebase/Firestore'

Databaseにアクセスするには、次のようにします。

    import Firebase
    FirebaseApp.configure()
    let db = Firestore.firestore()

Firestoreの基礎知識

Firestoreを使うにあたって知っておきたい基礎知識を紹介します。

データ構造

Firestoreのデータ構造は、DocumentとCollectionの主に2つで構成されます。Documentは1件のデータ、CollectionはDocumentの集まりです。Documentに直接書き込むことで、データの更新や削除などが行えます。データを検索したいときは、Collectionに対してクエリーを書くことで該当するDocumentを抽出することができます。

Collectionを使う方法

Collectionには、Documentを追加・削除することができます。また、ドキュメントの検索などもできます。usersのCollectionにアクセスするには、次のように書きます。

    db.collection("users")

Documentを使う方法

Documentには、Key Value形式でデータを保存することができます。user001のデータにアクセスするには、次のように書きます。

    db.collection("users").doc("user001")

書き込む方法

下記のように書くことで、ドキュメントにデータを書き込むことができます。 user002データを更新する例です。

    let data: [String: Any] = ["name":"Suzuki Hanako", "age": 21, "gender": "female"]
    db.collection("users").doc("user002").setData(data, merge: true)

取得方法

全件取得

usersコレクションのデータを全件取得する方法は以下の通りです。

    let collectionReference = db.collection("users")
    collectionReference.getDocuments { (_snapshot, _error) in
        if let error = _error {
            print(error.debugDescription)
            return
        }
    
    
        let datas = _snapshot!.documents.compactMap { $0.data() }
        print(datas)
        /*
            [
                { age: 20, gender: male, name: Tanaka Taro },
                { age: 21, gender: female, name: Suzuki Hanako }
            ]
        */
    }

1件取得

usersコレクションから特定のIDデータを取得することもできます。user0001のIDのユーザーデータを取得する例です。

    let documentReference = db.collection("users").doc("user001")
    documentReference.getDocument { (_snapshot, _error) in
        if let error = _error {
            print(error.debugDescription)
            return
        }
    
        let data = _snapshot!.data()
        print(data)
        /*
            { age: 20, gender: male, name: Tanaka Taro }
        */
    }

Query

Collectionに対して、Queryを使ってデータを検索することもできます。

    let collectionReference = db.collection("users").whereField("age", isEqualTo: 21)
    collectionReference.getDocuments { (_snapshot, _error) in
        if let error = _error {
            print(error.debugDescription)
            return
        }
    
        let datas = _snapshot!.documents.compactMap { $0.data() }
        print(datas)
        /*
            [
                { age: 21, gender: female, name: Suzuki Hanako }
            ]
        */
    }

Security Rule

Firestoreでは、データベースに対してセキュリティルールを設定することができます。設定することで、特定のデータに対する参照や書き込みを制限することができます。下記の例だと、認証済みのユーザーのみに読み込みを許可し、認証済みかつデータのユーザーIDと一致するユーザーのみ書き込みを許可するように設定してあります。

    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{user} {
          allow read: if request.auth != null;
          allow update: if request.auth != null
                         && request.auth.uid == request.resource.data.userId
                         && request.resource.data.userId == resource.data.userId;
          }
        }
      }
    }

Index

データに対してIndexを設定することで、データアクセスを早くすることができます。インデックスを作成するために書き込み時の処理が増えてしまう点に注意が必要です。

Copylight 01 NOTE