- Notifications
You must be signed in to change notification settings - Fork45
Combine wrapper on Google's iOS Firebase library.
License
urban-health-labs/CombineFirebase
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
HandlingFirebase asynchronous callbacks withCombine framework.
To run the example project, clone the repo, and runpod install
from the Example directory first. SeeUsage below for more information.
- Xcode 11.3+ | Swift 5.1+
- iOS 13.0+ | tvOS 13.0+ | macOS 10.15+
CombineFirebase
is available throughCocoaPods. To install it, simply add the following line to your Podfile:
pod'CombineFirebase/Firestore'pod'CombineFirebase/RemoteConfig'pod'CombineFirebase/Database'pod'CombineFirebase/Storage'pod'CombineFirebase/Auth'pod'CombineFirebase/Functions'
CombineFirebase
is available throughSwift Package Manager in beta status. To install it, you must haveXcode 12.0 and above, simply addCombineFirebase
to an existing Xcode project as a package dependency:
- From theFile menu, selectSwift Packages > Add Package Dependency...
- Enterhttps://github.com/rever-ai/CombineFirebase into the package repository URL text field.
- Xcode should choose updates package up to the next version option by default.
import CombineFirebaseimport Firebaseimport Combine
Basic write operation
varcancelBag=Set<AnyCancellable>()func setUserData(){letref=Database.database().reference() ref.child("users").child("1").setValue(["username":"Arnonymous"]).sink{ _inprint("Document successfully updated")}.store(in:&cancelBag)}// https://firebase.google.com/docs/database/ios/read-and-write#basic_write
Listen for value events
varcancelBag=Set<AnyCancellable>()func listenForValueEvent(){letref=Database.database().reference() ref.child("users").child("1").publisher(.value).receive(on:RunLoop.main).sink{ snapshotinprint("Value:\(snapshot.value)")}.store(in:&cancelBag)} // https://firebase.google.com/docs/database/ios/read-and-write#listen_for_value_events
Read data once
varcancelBag=Set<AnyCancellable>()func readDataOnce(){letref=Database.database().reference() ref.child("users").child("1").observeSingleEvent(.value).receive(on:RunLoop.main).sink{ snapshotinprint("Value:\(snapshot.value)")}.store(in:&cancelBag)} // https://firebase.google.com/docs/database/ios/read-and-write#read_data_once
Update specific fields
varcancelBag=Set<AnyCancellable>()func updateFields(){letref=Database.database().reference()letchildUpdates=["/posts/\(key)": post,"/user-posts/\(userID)/\(key)/": post] ref.updateChildValues(childUpdates).receive(on:RunLoop.main).sink{ _in // Success}.store(in:&cancelBag)}// https://firebase.google.com/docs/database/ios/read-and-write#update_specific_fields
Delete data
varcancelBag=Set<AnyCancellable>()func deleteData(){letref=Database.database().reference() ref.removeValue().receive(on:RunLoop.main).sink{ _in // Success}.store(in:&cancelBag)} // https://firebase.google.com/docs/database/ios/read-and-write#delete_data
Save data as transactions
varcancelBag=Set<AnyCancellable>()func saveDataAsTransaction(){letref=Database.database().reference() ref.runTransactionBlock{ currentDatain // TransactionResult}.sink{ _in // Success}.store(in:&cancelBag)} // https://firebase.google.com/docs/database/ios/read-and-write#save_data_as_transactions
Setting data
varcancelBag=Set<Cancellable>()letdb=Firestore.firestore()structCity:Codable{varname:String?=nilvarstate:String?=nilvarcountry:String?=nilvarcapital:String?=nilvarpopulation:Int?=nil // local variablevarid:String?=nil}func setSanFranciscoData(city:City){letonErrorCompletion:((Subscribers.Completion<Error>)->Void)?={ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}letonValue:(Void)->Void={print("✅ value")} // Add a new document in collection "cities"(db.collection("cities").document("SF").setData(from: city)asAnyPublisher<Void,Error>) // Note: you can use (as Void) for simple setData({}).sink(receiveCompletion: onErrorCompletion, receiveValue: onValue).store(in:&cancelBag)} // Add a new document with a generated id.func addSanFranciscoDocument(city:City){(db.collection("cities").addDocument(data:["name":"San Francisco","state":"CA","country":"USA","capital":false,"population":860000])asAnyPublisher<DocumentReference,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}){ refinprint("Document added with ID:\(ref.documentID)")}.store(in:&cancelBag)} // Set the "capital" field of the city 'SF'func updateSanFranciscoDocument(){(db.collection("cities").document("SF").updateData(["capital":true])asAnyPublisher<Void,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print(i"❗️ failure:\(error)")}){ _in}.store(in:&cancelBag)} // https://firebase.google.com/docs/firestore/manage-data/add-data
Get a document
func getDocument(){ db.collection("cities").document("SF").getDocument().sink(receiveCompletion:{(completion)inswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ documentinprint("Document data:\(document.data())")}.store(in:&cancelBag)}func getDocumentAsObject(){ db.collection("cities").document("SF").getDocument(as:City.self).sink(receiveCompletion:{(completion)inswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ cityinprint("City:\(city)")}.store(in:&cancelBag)} // https://firebase.google.com/docs/firestore/query-data/get-data
Get Realtime updates
letdb=Firestore.firestore()// Documentfunc listenDocument(){ db.collection("cities").document("SF").publisher().sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ documentinprint("Document data:\(document.data())")}.store(in:&cancelBag)}varcityDocumentSnapshotMapper:(DocumentSnapshot)throws->City?{{varcity=try $0.data(as:City.self) city.id= $0.documentIDreturn city}}func listenDocumentAsObject(){ db.collection("cities").document("SF").publisher(as:City.self, documentSnapshotMapper: cityDocumentSnapshotMapper).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ cityinprint("City:\(city)")}.store(in:&cancelBag)} // Collectionfunc listenCollection(){ db.collection("cities").publisher().sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ snapshotinprint("collection data:\(snapshot.documents)")}.store(in:&cancelBag)}func listenCollectionAsObject(){ db.collection("cities").publisher(as:City.self, documentSnapshotMapper: cityDocumentSnapshotMapper).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ citiesinprint("Cities:\(cities)")}.store(in:&cancelBag)}// https://firebase.google.com/docs/firestore/query-data/listen
Batched writes
varcancelBag=Set<AnyCancellable>()func batchWrite(){letdb=Firestore.firestore() // Get new write batchletbatch= db.batch() // Update the population of 'SF'letsfRef= db.collection("cities").document("SF") batch.updateData(["population":1000000], forDocument: sfRef) // Commit the batch batch.commit().sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ _in}.store(in:&cancelBag)} // https://firebase.google.com/docs/firestore/manage-data/transactions
Transactions
varcancelBag=Set<AnyCancellable>()func transaction(){letdb=Firestore.firestore()letsfReference= db.collection("cities").document("SF")(db.runTransaction{ transactioninletsfDocument=try transaction.getDocument(sfReference)guardlet oldPopulation= sfDocument.data()?["population"]as?Intelse{leterror=NSError( domain:"AppErrorDomain", code:-1, userInfo:[ NSLocalizedDescriptionKey:"Unable to retrieve population from snapshot\(sfDocument)"])throw error} transaction.updateData(["population": oldPopulation+1], forDocument: sfReference)returnnil}asAnyPublisher<Any?,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ _inprint("Transaction successfully committed!")}.store(in:&cancelBag)} // https://firebase.google.com/docs/firestore/manage-data/transactions
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.varcancelBag=Set<AnyCancellable>()func fetchRemoteConfig(){(RemoteConfig.remoteConfig().fetch(withExpirationDuration:TimeInterval(expirationDuration), activateFetched:true)asAnyPublisher<RemoteConfigFetchStatus,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("❗️ failure:\(error)")}}){ statusinprint("Config fetched! with success:\(status==.success)")}.store(in:&cancelBag)}// https://firebase.google.com/docs/remote-config/ios
Upload
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg")letdata:Data // Upload data(reference.putData(data)asAnyPublisher<StorageMetadata,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ metadatain // Success}.store(in:&cancelBag)letfileURL:URL // Upload file(reference.putFile(from: fileURL)asAnyPublisher<StorageMetadata,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ metadatain // Success}.store(in:&cancelBag)
Observe events
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg")letfileURL:URL // Upload fileletuploadTask= reference.putFile(from: fileURL)// Listen for state changesuploadTask.publisher(.progress).sink(receiveCompletion:{ _inprint("🏁 finished")}){ snapshotiniflet error= snapshot.error{print("error:\(error)")} // Upload reported progressletpercentComplete=100.0* Double(snapshot.progress?.completedUnitCount??0)/ Double(snapshot.progress.totalUnitCount??1)}.store(in:&cancelBag)
Download
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg")// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)(reference.getData(maxSize:1*1024*1024)asAnyPublisher<Data,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ datain // Data for "images/space.jpg" is returned}.store(in:&cancelBag) // Create local filesystem URLletlocalURL=URL(string:"path/to/image")! // Download to the local filesystem(reference.write(toFile: localURL)asAnyPublisher<URL,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ datain // Local file URL for "images/space.jpg" is returned}.store(in:&cancelBag)
URL
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg") // Fetch the download URL(reference.downloadURL()asAnyPublisher<URL,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ datain // Get the download URL for 'images/space.jpg'}.store(in:&cancelBag)
Metadata
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg") // Create file metadata to updateletnewMetadata=StorageMetadata() // Update metadata properties(reference.updateMetadata(newMetadata)asAnyPublisher<StorageMetadata,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ metadatain // Updated metadata for 'images/space.jpg' is returned}.store(in:&cancelBag) // Get metadata properties(reference.getMetadata()asAnyPublisher<StorageMetadata,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ metadatain // Metadata now contains the metadata for 'images/space.jpg'}.store(in:&cancelBag)
Delete
varcancelBag=Set<AnyCancellable>()letreference=Storage.storage().reference(forURL:"\(your_firebase_storage_bucket)/images/space.jpg") // Delete the file(reference.delete()asAnyPublisher<Void,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ _in // File deleted successfully}.store(in:&cancelBag)
Create
varcancelBag=Set<AnyCancellable>()letauth=Auth.auth() // Create a password-based account(auth.createUser(withEmail:"xxx@xxx.com", password:"1q2w3e4r")asAnyPublisher<AuthDataResult,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ _in // User signed in}.store(in:&cancelBag)// https://firebase.google.com/docs/auth/ios/password-auth
Sign in
varcancelBag=Set<AnyCancellable>()letauth=Auth.auth() // Sign in a user with an email address and password(auth.signIn(withEmail:"xxx@xxx.com", password:"1q2w3e4r")asAnyPublisher<AuthDataResult,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ _in // User signed in}.store(in:&cancelBag)// https://firebase.google.com/docs/auth/ios/password-auth
Update email
varcancelBag=Set<AnyCancellable>()letuser=Auth.auth().currentUser // Set a user's email address(user.updateEmail(to:"xxx@xxx.com")asAnyPublisher<Void,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ _in // Completed updating Email}.store(in:&cancelBag)// https://firebase.google.com/docs/auth/ios/manage-users
Delete
varcancelBag=Set<AnyCancellable>()letuser=Auth.auth().currentUser// Delete a user(user.delete()asAnyPublisher<Void,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error): // Uh-oh, an error occurred!}}){ _in // User deleted}.store(in:&cancelBag)// https://firebase.google.com/docs/auth/ios/manage-users
varcancelBag=Set<AnyCancellable>()letfunctions=Functions.functions()letrequest= functions.httpsCallable("functionName")(request.call(["parameter":"value"])asAnyPublisher<HTTPSCallableResult,Error>).sink(receiveCompletion:{ completioninswitch completion{case.finished:print("🏁 finished")case.failure(let error):print("error:\(error)")}}){ resultinprint("response:\(result)")}.store(in:&cancelBag) // https://firebase.google.com/docs/functions/callable#call_the_function
Kumar Shivang,shivang.iitk@gmail.com
CombineFirebase is available under the MIT license. See theLICENSE file for more info.
About
Combine wrapper on Google's iOS Firebase library.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors5
Uh oh!
There was an error while loading.Please reload this page.