はじめに
以前、Firestoreについて紹介しました。今回はリスナーを使用してドキュメントをリッスンする方法を紹介したいと思います。
リスナーのアタッチ
公式ドキュメントにある通り、リッスン(監視)したいドキュメント又はコレクションへ
addSnapshotListener
メソッドを使用し、リスナーをアタッチします。
以降、コンテンツに変更(追加・更新・削除)がある度に、コールバックを受け取る事が出来て、リアルタイムでアプリ側でも処理を行う事が可能となります。
ドキュメントのリッスン
具体的には以下の様にリッスンしたいドキュメントへリスナーをアタッチします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | override func viewDidLoad() { super.viewDidLoad() let db = Firestore.firestore() // "サンプル"ドキュメントにリスナーをアタッチする // コンテンツの変更がある際にコールバックを受け取り、コンソールにコメントを表示 db.collection("コレクション").document("サンプル").addSnapshotListener { (documentSnapshot, error) in // ドキュメントスナップショットの取得に失敗した場合はエラー内容を表示 guard let documentSnapshot = documentSnapshot else { print("Error fetching document: \(error!)") return } print("リスナーをアタッチして、コールバックを受け取った。") } } |
複数ドキュメントのリッスン
同じ様にコレクションへリスナーをアタッチすると、コレクション内の全ドキュメントをリッスン出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | override func viewDidLoad() { super.viewDidLoad() let db = Firestore.firestore() // "サブコレクション"内のドキュメント全てに対してリスナーをアタッチする // コンテンツの変更がある際にコールバックを受け取り、コンソールにコメントを表示 db.collection("コレクション").document("サンプル").collection("サブコレクション").addSnapshotListener { (documentSnapshot, error) in // ドキュメントスナップショットの取得に失敗した場合はエラー内容を表示 guard let documentSnapshot = documentSnapshot else { print("Error fetching document: \(error!)") return } print("リスナーをアタッチして、コールバックを受け取った。") } } |
ドキュメントの変更タイプの取得
.documentChanges
でスナップショットの変更内容の種別(追加・更新・削除)を配列で取得する事が出来ます。
よって、以下の通り種別毎に処理を分ける事も可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | override func viewDidLoad() { super.viewDidLoad() let db = Firestore.firestore() // "サブコレクション"内のドキュメント全てに対してリスナーをアタッチする // コンテンツの変更がある際にコールバックを受け取り、コンソールにコメントを表示 db.collection("コレクション").document("サンプル").collection("サブコレクション").addSnapshotListener { (documentSnapshot, error) in // ドキュメントスナップショットの取得に失敗した場合はエラー内容を表示 guard let documentSnapshot = documentSnapshot else { print("Error fetching document: \(error!)") return } // 変更内容の種別(追加、更新、削除)を取得し、種別毎に処理を分ける事も可能 documentSnapshot.documentChanges.forEach{ diff in if (diff.type == .added){ print("ドキュメントが追加された場合") } if (diff.type == .modified){ print("ドキュメントが変更された場合") } if (diff.type == .removed){ print("ドキュメントが削除された場合") } } } } |
リスナーのデタッチ
リスナーをデタッチする際は、
addSnapshotListener
で返却される
ListenerRegistration
から
remove()
メソッドを呼びます。
1 2 3 4 5 6 7 8 9 10 11 | override func viewDidLoad() { super.viewDidLoad() let db = Firestore.firestore() // リスナーをアタッチする際に、戻り値のListenerRegistraitonオブジェクトをlistenerに格納 let listener = db.collection("コレクション").document("サンプル").addSnapshotListener { (documentSnapshot, error) in // コールバックを受けった後の処理 } // リスナーのデタッチ listener.remove() } |
さいごに
FirestoreではサーバーレスでDBとのリアルタイム処理が簡単に実装する事が出来ます。
ぜひ一度試してみて下さい。