FirebaseServices is a Swift package that provides a convenient way to interact with various Firebase services, including Firestore, Storage, and Realtime Database.
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.
dependencies: [
.package(url: "https://github.com/DevCrew-io/firebase-utils-ios.git", .upToNextMajor(from: "1.0.0"))
]
To use FirebaseServices manually in your project, follow these steps:
-
Install the Firebase SDK by integrating it into your project using either Cocoapods or Swift Package Manager.
-
Add the FirebaseServices package to your project:
- Clone or download the FirebaseServices repository.
- Drag and drop the
FirebaseServices.xcodeproj
file into your Xcode project. - In your project's target settings, navigate to "General" -> "Frameworks, Libraries, and Embedded Content".
- Click the "+" button, select "FirebaseServices.framework", and choose "Add".
-
Import the FirebaseServices module wherever you need to use it:
import FirebaseServices
- Go to the Firebase Console, sign in with your Google account, create a new Firebase project or select an existing one and follow the steps mentioned by firebase to complete firebase configurations.
Note: Ensure that the GoogleService-Info.plist
file is included in your project's target and is present in your app's bundle during runtime.
To initialise FirebaseServiceManager
, In AppDelegate.swift:
import FirebaseServiceManager
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseServices.manager.configure()
return true
}
}
The FirebaseServices package provides the following services:
The FirestoreService
class is included within this package and is used for handling Firebase Firestore operations. Here's how you can use it:
// Example usage of FirestoreService
// Adding a document to the specified collection
FirebaseServices.manager.firestore.add(documentAt: yourCollectionPath, dataDic: yourDataDictionary) { result in
switch result {
case .success(let addedDocument):
// Handle success
print("Document added: \(addedDocument ?? nil)")
case .failure(let error):
// Handle error
print("Error adding document: \(error)")
}
}
// Retrieving a list of documents based on the provided query
FirebaseServices.manager.firestore.getList(YourFirestoreDocument.self, firestore: yourQuery) { result in
switch result {
case .success(let documents):
// Handle success
print("Retrieved documents: \(documents)")
case .failure(let error):
// Handle error
print("Error retrieving documents: \(error)")
}
}
// Retrieving a specific document from Firestore
FirebaseServices.manager.firestore.getDocument(with: documentId, from: yourCollection, YourFirestoreDocument.self) { result in
switch result {
case .success(let document):
// Handle success
print("Retrieved document: \(document ?? nil)")
case .failure(let error):
// Handle error
print("Error retrieving document: \(error)")
}
}
// Observing changes to a collection based on the provided query
let observerHandle = FirebaseServices.manager.firestore.observeDocuments(query: yourQuery, YourFirestoreDocument.self) { result in
switch result {
case .success(let documents):
// Handle success
print("Observed documents: \(documents)")
case .failure(let error):
// Handle error
print("Error observing documents: \(error)")
}
}
// Removing an observer
FirebaseServices.manager.firestore.removeObserver(handle: observerHandle)
// Updating a document in Firestore
FirebaseServices.manager.firestore.update(with: documentId, documentIn: yourCollection, dataDic: updatedDataDictionary) { result in
switch result {
case .success(let updatedDocument):
// Handle success
print("Document updated: \(updatedDocument ?? nil)")
case .failure(let error):
// Handle error
print("Error updating document: \(error)")
}
}
// Deleting a document from Firestore
FirebaseServices.manager.firestore.delete(id: documentId, documentAt: yourCollectionPath) { result in
switch result {
case .success(let deleted):
// Handle success
print("Document deleted: \(deleted)")
case .failure(let error):
// Handle error
print("Error deleting document: \(error)")
}
}
Similarly, all other methods can be used as per your need. To see all exposed methods/actions available in the package by navigating to FirestoreService
class.
To create FirestoreQuery
, use FSQuery.firestore
followed by your database path for example:
let firestoreQuery = FSQuery.firestore.collection("collectionPath")
The StorageService
class is used for handling Firebase Storage operations. Here's how you can use it:
// Example usage of StorageService
// Uploading a file to Firebase Storage
let data = ... // Your file data
let name = "example.jpg"
let folder = "images"
let metaData = StorageMetadata()
FirebaseServices.manager.storage.upload(file: data, with: name, in: folder, metaData: metaData, progressCompletion: { progress in
// Handle progress updates
}, completion: { result in
switch result {
case .success(let urls):
// Handle success
print("File uploaded successfully. URLs: \(urls)")
case .failure(let error):
// Handle error
print("Error uploading file: \(error)")
}
})
// Downloading data from Firebase Storage
let path = "images/example.jpg"
FirebaseServices.manager.storage.downloadData(from: path, progressCompletion: { progress in
// Handle progress updates
}, completion: { result in
switch result {
case .success(let data):
// Handle success
print("Downloaded data: \(data)")
case .failure(let error):
// Handle error
print("Error downloading data: \(error)")
}
})
// Deleting a file from Firebase Storage
FirebaseServices.manager.storage.delete(file: "example.jpg", colletion: "images") { result in
switch result {
case .success(let deleted):
// Handle success
if let deleted = deleted, deleted {
print("File deleted successfully.")
} else {
print("File does not exist.")
}
case .failure(let error):
// Handle error
print("Error deleting file: \(error)")
}
}
// Other available functions:
// - upload(file: Data, with name: String, in folder: String, metaData: StorageMetadata?, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<(String?, String?), Error>) -> ()) -> StorageUploadTask
// - update(file: Data, with name: String, in folder: String, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<(String?, String?), Error>) -> ()) -> StorageUploadTask
// - upload(file: URL, with name: String, in folder: String, metaData: StorageMetadata?, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<(String?, String?), Error>) -> ()) -> StorageUploadTask
// - update(file: URL, with name: String, in folder: String, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<(String?, String?), Error>) -> ()) -> StorageUploadTask
// - downloadData(from path: String, size: Int64 = Int64.max, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<Data?, Error>) -> Void) -> StorageDownloadTask
// - downloadFile(from path: String, to localURL: URL, progressCompletion: @escaping (_ progress: Progress) -> (), completion: @escaping (_ result: Result<URL?, Error>) -> Void) -> StorageDownloadTask
// - downloadURL(for path: String, completion: @escaping (_ result: Result<URL?, Error>) -> Void)
The DatabaseService
class is included within this package and is used for handling Firebase Realtime Database operations. Here's how you can use it:
// Example usage of DatabaseService
// Adding data to the database
FirebaseServices.manager.database.add(ref: yourDatabaseReference, dataDic: yourDataDictionary) { result in
switch result {
case .success(let addedData):
// Handle success
print("Data added: \(addedData ?? [:])")
case .failure(let error):
// Handle error
print("Error adding data: \(error)")
}
}
// Adding data using a custom object conforming to the `DatabaseNode` protocol
FirebaseServices.manager.database.add(ref: yourDatabaseReference, dataObject: yourCustomObject) { result in
switch result {
case .success(let addedObject):
// Handle success
if let addedObject = addedObject {
print("Object added: \(addedObject)")
} else {
print("Object not added.")
}
case .failure(let error):
// Handle error
print("Error adding object: \(error)")
}
}
// Updating data in the database
FirebaseServices.manager.database.update(ref: yourDatabaseReference, dataDic: updatedDataDictionary) { result in
switch result {
case .success(let updatedData):
// Handle success
print("Data updated: \(updatedData ?? [:])")
case .failure(let error):
// Handle error
print("Error updating data: \(error)")
}
}
// Updating data using a custom object conforming to the `DatabaseNode` protocol
FirebaseServices.manager.database.update(ref: yourDatabaseReference, dataObject: updatedCustomObject) { result in
switch result {
case .success(let updatedObject):
// Handle success
if let updatedObject = updatedObject {
print("Object updated: \(updatedObject)")
} else {
print("Object not updated.")
}
case .failure(let error):
// Handle error
print("Error updating object: \(error)")
}
}
// Retrieving a single object from the database
FirebaseServices.manager.database.getSingleObject(ref: yourDatabaseReference) { result in
switch result {
case .success(let object):
// Handle success
if let object = object {
print("Retrieved object: \(object)")
} else {
print("Object not found.")
}
case .failure(let error):
// Handle error
print("Error retrieving object: \(error)")
}
}
// Retrieving a list of objects from the database
FirebaseServices.manager.database.getList(ref: yourDatabaseReference) { result in
switch result {
case .success(let objects):
// Handle success
if let objects = objects {
print("Retrieved objects: \(objects)")
} else {
print("No objects found.")
}
case .failure(let error):
// Handle error
print("Error retrieving objects: \(error)")
}
}
// Observing changes in a list of objects in the database
let observerHandle = FirebaseServices.manager.database.observeList(ref: yourDatabaseReference) { result in
switch result {
case .success(let objects):
// Handle success
if let objects = objects {
print("Observed objects: \(objects)")
} else {
print("No objects observed.")
}
case .failure(let error):
// Handle error
print("Error observing objects: \(error)")
}
}
// Removing an observer
databaseService.removeObserver(ref: yourDatabaseReference, handle: observerHandle)
// Removing all registered observers
databaseService.removeAllObservers(ref: yourDatabaseReference)
Similarly, all other methods can be used as per your need. To see all exposed methods/actions available in the package by navigating to DatabaseService
class.
To create DatabaseReference
, use DBRef.database
followed by your database path for example:
let databaseReference = DBRef.database.child("your path")
If you have any questions or comments about FirebaseServicesManager , please feel free to contact us at info@devcrew.io.
Contributions, issues, and feature requests are welcome! See Contributors for details.
Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub.
Give a star if this project helped you.
Code copyright 2023 DevCrew I/O. Code released under the MIT license.