From a780112891a54ddc025c33e79ee3f151f0fc3c05 Mon Sep 17 00:00:00 2001 From: Arnaud Dorgans Date: Sun, 1 Apr 2018 00:02:55 +0200 Subject: [PATCH] fix --- README.md | 173 ++++++++++++++++++ .../Firestore/FIRCollectionReference+Rx.swift | 3 +- .../Firestore/FIRDocumentReference+Rx.swift | 10 +- .../Classes/Firestore/FIRFirestore+Rx.swift | 14 +- .../Classes/Firestore/FIRQuery+Rx.swift | 3 +- 5 files changed, 186 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4b01dd9..465653b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,179 @@ it, simply add the following line to your Podfile: pod 'RxFirebase' ``` +## Usage + +```swift + import RxFirebase +``` + +### Firestore + +Setting data: +```swift + let db = Firestore.firestore() + + // Add a new document in collection "cities" + db.collection("cities") + .document("SF") + .rx + .setData([ + "name": "San Francisco", + "state": "CA", + "country": "USA", + "capital": false, + "population": 860000 + ]).subscribe(onError: { error in + print("Error setting data: \(error)") + }).disposed(by: disposeBag) + + // Add a new document with a generated id. + db.collection("cities") + .rx + .addDocument(data: [ + "name": "San Francisco", + "state": "CA", + "country": "USA", + "capital": false, + "population": 860000 + ]).subscribe(onNext: { ref in + print("Document added with ID: \(ref.documentID)") + }, onError: { error in + print("Error adding document: \(error)") + }).disposed(by: disposeBag) + + // Set the "capital" field of the city 'SF' + db.collection("cities") + .document("SF") + .rx + .updateData([ + "capital": true + ]).subscribe(onNext: { + print("Document successfully updated") + }, onError: { error in + print("Error updating document: \(error)") + }).disposed(by: disposeBag) + + // https://firebase.google.com/docs/firestore/manage-data/add-data +``` + +Get a document +```swift + let db = Firestore.firestore() + + db.collection("cities") + .document("SF") + .rx + .getDocument() + .subscribe(onNext: { document in + if let document = document { + print("Document data: \(document.data())") + } else { + print("Document does not exist") + } + }, onError: { error in + print("Error fetching snapshots: \(error)") + }).disposed(by: disposeBag) + + // https://firebase.google.com/docs/firestore/query-data/get-data +``` + +Get Realtime Updates +```swift + let db = Firestore.firestore() + + // Document + db.collection("cities") + .document("SF") + .rx + .listen() + .subscribe(onNext: { document in + print("Current data: \(document.data())") + }, onError: { error in + print("Error fetching snapshots: \(error)") + }).disposed(by: disposeBag) + + // Collection + db.collection("cities") + .rx + .listen() + .subscribe(onNext: { snapshot in + snapshot.documentChanges.forEach { diff in + if (diff.type == .added) { + print("New city: \(diff.document.data())") + } + if (diff.type == .modified) { + print("Modified city: \(diff.document.data())") + } + if (diff.type == .removed) { + print("Removed city: \(diff.document.data())") + } + } + }, onError: { error in + print("Error fetching snapshots: \(error)") + }).disposed(by: disposeBag) + + // https://firebase.google.com/docs/firestore/query-data/listen +``` + +Batched writes +```swift + let db = Firestore.firestore() + + // Get new write batch + let batch = db.batch() + + // Update the population of 'SF' + let sfRef = db.collection("cities").document("SF") + batch.updateData(["population": 1000000 ], forDocument: sfRef) + + // Commit the batch + batch.rx + .commit() + .subscribe(onNext: { + print("Batch write succeeded.") + }, onError: { error in + print("Error writing batch \(error)") + }).disposed(by: disposeBag) + + // https://firebase.google.com/docs/firestore/manage-data/transactions +``` + +Transactions +```swift + let db = Firestore.firestore() + let sfReference = db.collection("cities").document("SF") + + db.rx.runTransaction { transaction, errorPointer in + let sfDocument: DocumentSnapshot + do { + try sfDocument = transaction.getDocument(sfReference) + } catch let fetchError as NSError { + errorPointer?.pointee = fetchError + return nil + } + + guard let oldPopulation = sfDocument.data()?["population"] as? Int else { + let error = NSError( + domain: "AppErrorDomain", + code: -1, + userInfo: [ + NSLocalizedDescriptionKey: "Unable to retrieve population from snapshot \(sfDocument)" + ] + ) + errorPointer?.pointee = error + return nil + } + + transaction.updateData(["population": oldPopulation + 1], forDocument: sfReference) + return nil + }.subscribe(onNext: { _ in + print("Transaction successfully committed!") + }, onError: { error in + print("Transaction failed: \(error)") + }).disposed(by: disposeBag) +`` + ## Author Arnaud Dorgans, arnaud.dorgans@gmail.com diff --git a/RxFirebase/Classes/Firestore/FIRCollectionReference+Rx.swift b/RxFirebase/Classes/Firestore/FIRCollectionReference+Rx.swift index 4815da2..c8247c9 100644 --- a/RxFirebase/Classes/Firestore/FIRCollectionReference+Rx.swift +++ b/RxFirebase/Classes/Firestore/FIRCollectionReference+Rx.swift @@ -25,7 +25,7 @@ extension Reactive where Base: CollectionReference { public func addDocument(data: [String: Any]) -> Observable { return Observable.create { observer in var ref: DocumentReference? - let _ref = self.base.addDocument(data: data) { error in + ref = self.base.addDocument(data: data) { error in if let error = error { observer.onError(error) } else if let ref = ref { @@ -33,7 +33,6 @@ extension Reactive where Base: CollectionReference { } observer.onCompleted() } - ref = _ref return Disposables.create() } } diff --git a/RxFirebase/Classes/Firestore/FIRDocumentReference+Rx.swift b/RxFirebase/Classes/Firestore/FIRDocumentReference+Rx.swift index 5ce8f8e..32f1992 100644 --- a/RxFirebase/Classes/Firestore/FIRDocumentReference+Rx.swift +++ b/RxFirebase/Classes/Firestore/FIRDocumentReference+Rx.swift @@ -113,14 +113,13 @@ extension Reactive where Base: DocumentReference { * * @param completion a block to execute once the document has been successfully read. */ - public func getDocument() -> Observable { - return Observable.create { observer in + public func getDocument() -> Observable { + return Observable.create { observer in self.base.getDocument { snapshot, error in if let error = error { observer.onError(error) - } else if let snapshot = snapshot { - observer.onNext(snapshot) } + observer.onNext(snapshot) observer.onCompleted() } return Disposables.create() @@ -135,7 +134,7 @@ extension Reactive where Base: DocumentReference { * * @return A FIRListenerRegistration that can be used to remove this listener. */ - public func addSnapshotListener(options: DocumentListenOptions? = nil) -> Observable { + public func listen(options: DocumentListenOptions? = nil) -> Observable { return Observable.create { observer in let listener = self.base.addSnapshotListener(options: options) { snapshot, error in if let error = error { @@ -143,7 +142,6 @@ extension Reactive where Base: DocumentReference { } else if let snapshot = snapshot { observer.onNext(snapshot) } - observer.onCompleted() } return Disposables.create { listener.remove() diff --git a/RxFirebase/Classes/Firestore/FIRFirestore+Rx.swift b/RxFirebase/Classes/Firestore/FIRFirestore+Rx.swift index 12b836d..f961f8d 100644 --- a/RxFirebase/Classes/Firestore/FIRFirestore+Rx.swift +++ b/RxFirebase/Classes/Firestore/FIRFirestore+Rx.swift @@ -17,7 +17,7 @@ extension Reactive where Base: Firestore { * will return results from cache and any write operations will be queued until the network is * restored. The completion block, if provided, will be called once network usage has been disabled. */ - func disableNetwork() -> Observable { + public func disableNetwork() -> Observable { return Observable.create { observer in self.base.disableNetwork(completion: { error in guard let error = error else { @@ -36,7 +36,7 @@ extension Reactive where Base: Firestore { * `disableNetworkWithCompletion`. Completion block, if provided, will be called once network uasge * has been enabled. */ - func enableNetwork() -> Observable { + public func enableNetwork() -> Observable { return Observable.create { observer in self.base.enableNetwork(completion: { error in guard let error = error else { @@ -78,15 +78,15 @@ extension Reactive where Base: Firestore { * @param completion The block to call with the result or error of the transaction. This * block will run even if the client is offline, unless the process is killed. */ - func runTransaction(_ updateBlock: @escaping (Transaction, NSErrorPointer)->Any?) -> Observable { + public func runTransaction(_ updateBlock: @escaping (Transaction, NSErrorPointer)->Any?) -> Observable { return Observable.create { observer in self.base.runTransaction(updateBlock) { value, error in - if let error = error { - observer.onError(error) - } else if let value = value { + guard let error = error else { observer.onNext(value) + observer.onCompleted() + return } - observer.onCompleted() + observer.onError(error) } return Disposables.create() } diff --git a/RxFirebase/Classes/Firestore/FIRQuery+Rx.swift b/RxFirebase/Classes/Firestore/FIRQuery+Rx.swift index 387a167..639c7d3 100644 --- a/RxFirebase/Classes/Firestore/FIRQuery+Rx.swift +++ b/RxFirebase/Classes/Firestore/FIRQuery+Rx.swift @@ -39,7 +39,7 @@ extension Reactive where Base: Query { * * @return A FIRListenerRegistration that can be used to remove this listener. */ - public func addSnapshotListener(options: QueryListenOptions? = nil) -> Observable { + public func listen(options: QueryListenOptions? = nil) -> Observable { return Observable.create { observer in let listener = self.base.addSnapshotListener(options: options) { snapshot, error in if let error = error { @@ -47,7 +47,6 @@ extension Reactive where Base: Query { } else if let snapshot = snapshot { observer.onNext(snapshot) } - observer.onCompleted() } return Disposables.create { listener.remove()