8
5

More than 3 years have passed since last update.

Firebase FireStore使ってみた

Posted at

対象

これからFireStoreを使ってみようと思っているiOSエンジニア

FireStoreとは

Firebaseが提供しているデータベースです。
MySQLなどのRDB(リレーショナルデータベース)の行列とは違い、「コレクション」「ドキュメント」「データ」の3つで構成されています。

structure-data.png

また、アプリとの直接的なやりとりでDBのデータを直接取得できます。

料金

無料枠
保存量 1GB
通信量 10GB/月
書き込み量 2/日
読み取り量 5/日
削除量 2/日
有料
保存量1GBあたり $0.18
通信量 ロケーションにより異なる
書き込み量10万件あたり $0.18
読み取り量10万件あたり $0.06
削除量10万件あたり $0.02

Firebaseから出ているDBには、もう1つ「Realtime Database」もあります。
こちらとの機能的な違いもありますが、料金体系も違います。
「Realtime Database」は保存量などに課金されますが、「FireStore」は書き込み/読み取り回数に課金されます。

Firebaeプロジェクトをアプリへ追加する

こちらを参考にアプリへFirebaeプロジェクトを追加してください。

インストール(アプリへ追加)

Podファイルへの記載

Podfile.

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

インストール

ターミナル.
Xcodeプロジェクトのあるディレクトリ $ pod install

アプリ内で初期化

AppDelegate.swift
import Firebase

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()

return true
}

以上で、アプリ内で、FireStoreが使えるようになります。

データの追加

Firestore.swift
// FIRFirestoreインスタンスの作成
    let db = Firestore.firestore()
// 「users」コレクションの作成(ドキュメント名指定)
    func creatUserCollectionDesignationDocument() {
        // "users"という名称のコレクションを作成
        // "hoge"という名称のドキュメントを作成
        // ["name": "hoge"]というデータを保存
        db.collection("users").document("hoge").setData(["name": "hoge"]) { error in
            if let error = error {
                print("エラーが起きました")
            }
            else {
                print("ドキュメント「hoge」が保存できました")
            }
        }
    }
// usersコレクションの作成(ドキュメント名自動)
    func creatUserCollectionAutomaticDocument() {
        // "users"という名称のコレクションを作成
        // ドキュメント名を自動でを作成
        // ["name": "hoge"]というデータを保存
        db.collection("users"). addDocument(["name": "hoge"]) { error in
            if let error = error {
                print("エラーが起きました")
            }
            else {
                print("ドキュメントが保存できました")
            }
        }
    }

同名のドキュメントがあった場合は、上書きされてしまいます。
同名ドキュメントがあった場合は、データを加算させる
無かった場合は、新規で追加したい場合は、「merge: true」をつける

Firestore.swift
// 「users」コレクションの作成(ドキュメント名指定)
    func creatDocumentSaveOrUpdate() {
        // "hoge"という名称のドキュメント に対して
        // ["age": "20"]というデータを保存
        db.collection("users").document("hoge").setData(["age": 20], merge: true) { error in
            if let error = error {
                print("エラーが起きました")
            } 
            else {
                print("ドキュメント「hoge」が保存できました")
            }
        }
    }

Document:hogeがあったら、
["name": "hoge",
"age": 20]

無かったら、
["age": "20"]

と、なります。

データの削除

Firestore.swift
// FIRFirestoreインスタンスの作成
    let db = Firestore.firestore()
// usersコレクション内のhogeドキュメントの削除
    func deleteDocument() {
        db.collection("users").document("hoge").delete() { err in
            if let err = err {
                print("Error removing document: \(err)")
            } 
            else {
                print("Document successfully removed!")
            }
        }
    }
// hogeドキュメント内の「"name": "hoge"」の削除
    func deleteDocument() {
        db.collection("users").document("hoge").updateData([
            "name": FieldValue.delete(),
        ]) { err in
            if let err = err {
                print("Error updating document: \(err)")
            } 
            else {
                print("Document successfully updated")
            }
        }
    }

コレクションを削除したい場合は、コレクション内のドキュメントを全て削除する必要があります。

データの検索

Firestore.swift
// FIRFirestoreインスタンスの作成
  let db = Firestore.firestore()
// コレクション「user」内の全ドキュメント取得
  func fetchDocument() {
    db.collection("user").getDocuments() { (querySnapshot, err) in
        if let err = err {
          print("Error getting documents: \(err)")
        }
         else {
            for document in querySnapshot!.documents {
                print("\(document.documentID) => \(document.data())")
            }
        }
     }
  }
// 特定のドキュメントを指定してそのドキュメント内のデータ全てを取得
  func fetchDocument() {
     db.collection("user").document("hoge").getDocument { (document, error) in
        if let document = document, document.exists {
            let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
            print("Document data: \(dataDescription)")
        } 
        else {
            print("Document does not exist")
        }
     }
  }

スナップショップ・リスナー(自動同期)

検索に「addSnapshotListener」を付与します。

Firestore.swift
// FIRFirestoreインスタンスの作成
  let db = Firestore.firestore()
// ドキュメント「hoge」に対して、取得とスナップショップを設定
  func fetchDocumentSnapshotListener() {
     db.collection("user").document("hoge").addSnapshotListener { (querySnapshot, err) in
         if let err = err {
            print("Error getting documents: \(err)")
         } 
          else {
            for document in querySnapshot!.documents {
                print("\(document.documentID) => \(document.data())")
            }
         }
     }
  }

条件

Firestore.swift
  // FIRFirestoreインスタンスの作成
    let db = Firestore.firestore()
  // コレクション「user」に対して、条件(nameがhoge)に一致したドキュメントを取得する
    func fetchDocumentSnapshotListener() {
      db.collection("user").whereField("name", isEqualTo: "hoge").getDocument() { (querySnapshot, err) in
           if let err = err {
              print("Error getting documents: \(err)")
           } 
           else {
              for document in querySnapshot!.documents {
                  print("\(document.documentID) => \(document.data())")
              }
           }
       }
    }
    // コレクション「user」に対して、複数条件(nameがhoge かつ ageが18以上)に一致したドキュメントを取得する
      func fetchDocumentSnapshotListener() {
        db.collection("user").whereField("name", isEqualTo: "hoge").
                              whereField("age", isGreaterThanOrEqualTo: 18).getDocument() { (querySnapshot, err) in
             if let err = err {
                print("Error getting documents: \(err)")
             } 
             else {
                for document in querySnapshot!.documents {
                    print("\(document.documentID) => \(document.data())")
                }
             }
         }
      }

Swiftの場合、比較演算子はメソッド名になっています。

演算子 メソッド名
== isEqualTo
< isLessThan
> isGreaterThan
<= isLessThanOrEqualTo
>= isGreaterThanOrEqualTo
配列内に指定した要素があったら arrayContains

足らないこと、間違い等ありましたら、コメントもしくは、@gurensouen
にご連絡いただけますと幸いです。

8
5
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
8
5