カテゴリー: iOS

iOSでFirestoreを使ってみた

はじめに

こんにちは、Yossyです。
今回も個人で作成中のアプリで使用しているFirebase機能の中から、
Firebase Cloud Firestoreの紹介をしたいと思います。

Cloud Firestoreとは

iOSやAndroidからネイティブ SDK を介して直接アクセスできるNoSQL ドキュメント志向クラウドデータベースです。
サーバー側の実装が必要なく、クライアントのみの実装でクラウドデータベースとのやり取りを行う事が出来ます。

仕組み

公式では次の通りに説明されています。

NoSQL データモデルに従い、値に対応するフィールドを含むドキュメントにデータを格納します。これらのドキュメントはコレクションに格納されます。コレクションは、データの編成とクエリの作成に使用できるドキュメントのコンテナです。

ドキュメントとは

データを格納するストレージ。値にマッピングされるフィールドを含む軽量のレコードです。各ドキュメントは名前で識別されます。
サポートされているデータ型はこちらの通りです。
例えば、以下の様にidnameを持ったuser1というドキュメント作成出来ます。

user1{
  id:12345
  name:"ユーザー1"
}

コレクションとは

データを格納するコンテナです。複数のデータを格納する事が出来ます。
コレクション自体を作成する必要はなく、最初のドキュメントを作成する際に自動でコレクションも作成されます。
コレクション内の全てのドキュメントを削除すると、コレクションも削除されます。
例えば、以下の様にusersというコレクションに、user1user2という2つのドキュメントを格納する事が出来ます。

users{
  user1{
    id: 12345
    name:"ユーザー1"
  }

  user2 {
    id: 67890
    name:"ユーザー2"
  }
}

サブコレクションとは

ドキュメント内に保存されたコレクションを指します。
このサブコレクションによって、データを階層的に保存する事が出来ます。
例えば、以下の様にuser1のドキュメント内にitemsというサブコレクションを作成する事が出来ます。
itemsの中にはitem1item2の2つのドキュメントが格納されています。

users{
  user1{
    id:12345
    name:"ユーザー1"
    items{
      item1{
        name:"アイテム1"
        price:100
      }
      item2{
        name:"アイテム2"
        price:200
      }
    }
  }
  user2{
    id:67890
    name:"ユーザー2"
  }
}

データの保存

新規保存

実際にデータを保存してみたいと思います。
事前準備としてFirebaseプロジェクトの作成とデータベースの作成を行っておきます。
作り方はこちらを参照ください。
まず、Firestore.firestore()を呼び出し、Cloud Firestoreの初期化とFIRFirestoreインスタンスの取得を行います。
setData( )メソッドを使い、引数に保存したいデータを指定します。
コレクションは、ドキュメントを新規保存する際に自動的に作成されますので、名称だけ指定してあげます。

// FIRFirestoreインスタンスの作成
    let db = Firestore.firestore()

// usersコレクションの作成
    func creatUserCollection( ) {
        // "users"という名称のコレクションを作成
        // "user1"という名称のドキュメントを作成
        db.collection("users").document("user1").setData(["data": "userData"]) { error in
            if let error = error {
                print("エラーが起きました")
            } else {
                print("ドキュメントが保存されました")
            }
        }
    }

実際にコンソール画面で確認すると、usersというコレクションにuser1ドキュメントが保存されている事が確認出来ます。

追加

既存のドキュメントにデータを追加したい場合は、setData()メソッドに引数(merge:true)を追加します。
既存のデータを上書きせずに、データを追加する事が出来ます。

    func addDocument() {
        // "users"コレクションの"user1"ドキュメントにデータを追加
        // "merge: true"の引数を取る事で、ドキュメントのデータ全体の上書をしない
        db.collection("users").document("user1").setData(["add": "addData"], merge: true) { error in
            if let error = error {
                print("エラーが起きました")
            } else {
                print("ドキュメントが保存されました")
            }
        }
    }

こちらも、コンソール画面で確認すると先程のドキュメントにデータが追加されている事が確認出来ます。

サブコレクションの保存

サブコレクションを保存する際は、ドキュメントの中で、コレクションと配下のドキュメントを作成します。

     func subCollection() {
        // "user1"ドキュメント内に、"subUsers"サブコレクションを作成
        // "subUsers"内に、"subuser1"ドキュメントを作成
        db.collection("users").document("user1").collection("subUsers").document("subuser1")
            .setData(["sub": "subData"]){ error in
                if let error = error {
                    print("エラーが起きました")
                } else {
                    print("ドキュメントが保存されました")
                }
        }
    }

コンソール画面で確認すると、ドキュメントの中にサブコレクションが作成されている事が確認出来ます。

データの取得

データを取得する際は、データの参照パスを示すリファレンスオブジェクトを使用します。
公式では次の通りにリファレンスの事が説明されています。

リファレンスは、データベース内の場所を参照するだけの軽量なオブジェクトです。リファレンスはそこにデータが存在するかどうかにかかわらず作成することができ、リファレンスを作成してもネットワーク操作は実行されません。

単一ドキュメント

ドキュメントより単一ドキュメントを取得したいと思います。
まずは、ドキュメントまでのリファレンスを作成します。
リファレンス作成後に、getDocument( )メソッドでデータを取得します。

    func getDocument() {
        // "subuser1"ドキュメントへの参照を示す、"ref"リファレンスオブジェクトを作成
        let ref = db.collection("users").document("user1").collection("subUsers").document("subuser1")
        // getDocument()メソッドでデータを取得
        ref.getDocument{ (document, error) in
            if let document = document{
                print(document.data()!) // ["sub": subData]
            }
        }
    }

複数ドキュメント

複数のドキュメントを取得したいと思います。
取得したいドキュメントが格納されているコレクションまでのリファレンスを作成します。
リファレンス作成後に、getDocuments( )メソッドで、配下のドキュメントを全て取得します。

 
    func getDocuments() {
        // "subUsers"コレクションへの参照を示す、"ref"リファレンスオブジェクトを作成
        let ref = db.collection("users").document("user1").collection("subUsers")
        // getDocuments()メソッドでデータを取得
        ref.getDocuments{ (querySnapshot, err) in
            for document in querySnapshot!.documents{
                print(document.data()) // ["sub": subData], ["sub": subData2]
            }
        }
    }

さいごに

Firebase Cloud Firestoreを利用すれば、サーバーサイドの実装の手間を省いてオンラインデータベースを利用出来て便利です。
他に、クエリ機能でデータを検索して取得したり、ドキュメントにリスナーを付けてリアルタイム処理を行ったりも可能です。
その辺りの事も書きたいと思います。

おすすめ書籍

Yossy

シェア
執筆者:
Yossy
タグ: SwiftFirebase

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前