RxSwiftCommunity / Rxfirebase
Licence: mit
RxSwift extensions for Firebase
Stars: ✭ 195
Programming Languages
swift
15916 projects
RxFirebase
Requirements
Xcode 9.0
Swift 4.0
Installation
RxFirebase is available through CocoaPods. To install it, simply add the following lines to your Podfile:
pod 'RxFirebase/Firestore'
pod 'RxFirebase/RemoteConfig'
pod 'RxFirebase/Database'
pod 'RxFirebase/Storage'
pod 'RxFirebase/Auth'
pod 'RxFirebase/Functions'
Usage
import RxFirebase
Database
Basic write operation:
let ref = Database.database().reference()
ref.child("users")
.child("1")
.rx
.setValue(["username": "Arnonymous"])
.subscribe(onNext: { _ in
print("Document successfully updated")
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#basic_write
Listen for value events:
let ref = Database.database().reference()
ref.child("users")
.child("1")
.rx
.observeEvent(.value)
.subscribe(onNext: { snapshot in
print("Value:\(snapshot.value)")
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#listen_for_value_events
Read data once:
let ref = Database.database().reference()
ref.child("users")
.child("1")
.rx
.observeSingleEvent(.value)
.subscribe(onNext: { snapshot in
print("Value:\(snapshot.value)")
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#read_data_once
Update specific fields:
let ref = Database.database().reference()
let childUpdates = ["/posts/\(key)": post,
"/user-posts/\(userID)/\(key)/": post]
ref.rx.updateChildValues(childUpdates)
.subscribe(onNext: { _ in
// Success
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#update_specific_fields
Delete data:
let ref = Database.database().reference()
ref.rx.removeValue()
.subscribe(onNext: { _ in
// Success
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#delete_data
Save data as transactions
let ref = Database.database().reference()
ref.rx.runTransactionBlock { currentData in
// TransactionResult
}.subscribe(onNext: { _ in
// Success
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/database/ios/read-and-write#save_data_as_transactions
Firestore
Setting data:
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:
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:
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:
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:
let db = Firestore.firestore()
let sfReference = db.collection("cities").document("SF")
db.rx.runTransaction { transaction in
let sfDocument = try transaction.getDocument(sfReference)
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)"
]
)
throw error
}
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)
// https://firebase.google.com/docs/firestore/manage-data/transactions
RemoteConfig
Fetch:
// TimeInterval is set to expirationDuration here, indicating the next fetch request will use
// data fetched from the Remote Config service, rather than cached parameter values, if cached
// parameter values are more than expirationDuration seconds old. See Best Practices in the
// README for more information.
RemoteConfig.remoteConfig()
.rx
.fetch(withExpirationDuration: TimeInterval(expirationDuration), activateFetched: true)
.subscribe(onNext: { status in
print("Config fetched! with success:\(status == .success)")
}, onError: { error in
print("Error: \(error)")
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/remote-config/ios
Storage
Upload:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
let data: Data // Upload data
reference.putData(data)
.subscribe(onNext: { metadata in
// Success
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
let fileURL: URL // Upload file
reference.putFile(from: fileURL)
.subscribe(onNext: { metadata in
// Success
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
Observe events:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
let fileURL: URL // Upload file
let uploadTask = reference.putFile(from: fileURL)
// Listen for state changes
uploadTask.rx.observe(.progress)
.subscribe(onNext: { snapshot in
// Upload reported progress
let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
/ Double(snapshot.progress!.totalUnitCount)
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
Download:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
reference.getData(maxSize: 1 * 1024 * 1024)
.subscribe(onNext: { data in
// Data for "images/space.jpg" is returned
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// Create local filesystem URL
let localURL = URL(string: "path/to/image")!
// Download to the local filesystem
reference.write(toFile: localURL)
.subscribe(onNext: { data in
// Local file URL for "images/space.jpg" is returned
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
URL:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
// Fetch the download URL
reference.downloadURL()
.subscribe(onNext: { url in
// Get the download URL for 'images/space.jpg'
}, onError: { error in
// Handle any errors
}).disposed(by: disposeBag)
Metadata:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
// Create file metadata to update
let newMetadata = StorageMetadata()
// Update metadata properties
reference.updateMetadata(newMetadata)
.subscribe(onNext: { metadata in
// Updated metadata for 'images/space.jpg' is returned
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// Get metadata properties
reference.getMetadata()
.subscribe(onNext: { metadata in
// Metadata now contains the metadata for 'images/space.jpg'
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
Delete:
let reference = Storage.storage()
.reference(forURL: "\(your_firebase_storage_bucket)/images/space.jpg")
.rx
// Delete the file
reference.delete()
.subscribe(onNext: {
// File deleted successfully
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
Auth
Create:
let auth = Auth.auth()
// Create a password-based account
auth.rx.createUser(withEmail: "[email protected]", password: "1q2w3e4r")
.subscribe(onNext: { authResult in
// User signed in
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/auth/ios/password-auth
Sign In:
let auth = Auth.auth()
// Sign in a user with an email address and password
auth.rx.signIn(withEmail: "[email protected]", password: "1q2w3e4r")
.subscribe(onNext: { authResult in
// User signed in
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/auth/ios/password-auth
User
Update Email:
let user = Auth.auth().currentUser?
// Set a user's email address
user.rx.updateEmail(to: "[email protected]")
.subscribe(onNext: {
// Completed updating Email
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/auth/ios/manage-users
Delete:
let user = Auth.auth().currentUser?
// Delete a user
user.rx.delete()
.subscribe(onNext: {
// User deleted
}, onError: { error in
// Uh-oh, an error occurred!
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/auth/ios/manage-users
Functions
let functions = Functions.functions()
let request = functions.httpsCallable("functionName").rx
request
.call(["parameter": "value"])
.subscribe(onNext: { result in
print("response:\(result)")
}, onError: { error in
print("error:\(error)")
}).disposed(by: disposeBag)
// https://firebase.google.com/docs/functions/callable#call_the_function
License
This library belongs to RxSwiftCommunity.
RxFirebase is available under the MIT license. See the LICENSE file for more info.
Note that the project description data, including the texts, logos, images, and/or trademarks,
for each open source project belongs to its rightful owner.
If you wish to add or remove any projects, please contact us at [email protected].