Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/RxSwiftCommunity/RxFirebase

RxSwift extensions for Firebase
https://github.com/RxSwiftCommunity/RxFirebase

Last synced: about 2 months ago
JSON representation

RxSwift extensions for Firebase

Awesome Lists containing this project

README

        

# RxFirebase

[![CI Status](http://img.shields.io/travis/RxSwiftCommunity/RxFirebase.svg?style=flat)](https://travis-ci.org/RxSwiftCommunity/RxFirebase)
[![Version](https://img.shields.io/cocoapods/v/RxFirebase.svg?style=flat)](http://cocoapods.org/pods/RxFirebase)
[![License](https://img.shields.io/cocoapods/l/RxFirebase.svg?style=flat)](http://cocoapods.org/pods/RxFirebase)
[![Platform](https://img.shields.io/cocoapods/p/RxFirebase.svg?style=flat)](http://cocoapods.org/pods/RxFirebase)

## Requirements

Xcode 9.0

Swift 4.0

## Installation

RxFirebase is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following lines to your Podfile:

```ruby
pod 'RxFirebase/Firestore'
pod 'RxFirebase/RemoteConfig'
pod 'RxFirebase/Database'
pod 'RxFirebase/Storage'
pod 'RxFirebase/Auth'
pod 'RxFirebase/Functions'
```

## Usage

```swift
import RxFirebase
```

- [Database](#database)
- [Firestore](#firestore)
- [RemoteConfig](#remoteconfig)
- [Storage](#storage)
- [Auth](#auth)
- [Functions](#functions)

### Database

Basic write operation:
```swift
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:
```swift
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:
```swift
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:
```swift
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:
```swift
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
```swift
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:
```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 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:
```swift
// 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:
```swift

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:
```swift
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:
```swift
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:
```swift
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:
```swift
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:
```swift
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:

```swift
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:

```swift
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:

```swift
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:

```swift
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

```swift
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.