10
7

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.

RxSwift Firebase Firestore データ取得メモ

10
Last updated at Posted at 2018-10-18

Firebase FirestoreのデータをRxSwiftで取得するためのメモ

メモなので今後も追記予定

    func getData() -> Observable<[Model]?> {
        guard let uid = Auth.auth().currentUser?.uid else { return Observable.just(nil) }
        return Observable.create { (observer: AnyObserver<Model?>) -> Disposable in
            Firestore.firestore().document("path to data/\(uid)").getDocument { (document, error) in
                if let error = error {
                    observer.onError(error)
                    return
                }
                guard let document = document, document.exists else {
                    observer.onError( /* データなしエラー */ )
                    return
                }
                // DocumentSnapshottから変換して返す
                let model = try? Model(from: document)
                observer.on(.next(model))
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }

RxFirebaseを使う場合

    func getData() -> Observable<[Model]?> {
        guard let uid = Auth.auth().currentUser?.uid else { return Observable.just(nil) }
        return database.collection("path to datas").document(uid).rx.getDocument().map(Model.init)
    }

オプショナルをなくす場合

    func getData() -> Observable<[Model]> {
        guard let uid = Auth.auth().currentUser?.uid else { return Observable.error( /* 定義していた何かのエラー */ ) }
        return database.collection("path to datas").document(uid).rx.getDocument().map(Model.init)
    }

利用例

Category というモデルがある場合
Serviceクラスを作成

class CategoryService {

    private static let database = Firestore.firestore()

    static func getCategories() -> Observable<[Category]> {

       return database.collection("/category")
                .whereField("status", isEqualTo: 1)
                .rx.getDocuments()                  // QuerySnapshot
                .map { $0.documents }               // [QueryDocumentSnapshot]
                .map { $0.compactMap{ doc in return try? Category.init(from: doc) } } // [Category]
    }

}

ViewModel はこんな風に

class ViewModel {

    let categories: Driver<[Category]>
    let error: Driver<Error>

    init () {
         (self.categories, self.error) = Driver.split(result: CategoryService.getCategories().resultDriver())
    }
}
class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    private var viewModel: ViewModel!
    let caategories = BehaviorRelay<[Category]?>(value: [])

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        // データ取得
        self.viewModel = ViewModel()

        // カテゴリ情報を bind
        self.viewModel.categories.asObservable()
            .bind(to: self.caategories)
            .disposed(by: rx.disposeBag)

        // カテゴリ情報を bind した後に一覧を更新
        self.caategories.asDriver().drive(onNext: { [unowned self] _ in
            self.tableView.reloadData()
        }).disposed(by: rx.disposeBag)
    }
}
10
7
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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?