https://github.com/Flowductive/easy-firebase
🔥 A Swifty solution for all things Firebase. Quickly implement Firestore and Authentication on iOS + macOS using Swift protocols and methods.
https://github.com/Flowductive/easy-firebase
authentication cloud-messaging firebase firebase-auth firebase-storage firestore ios macos push-notifications sign-in-with-apple sign-in-with-google signinwithapple signinwithgoogle storage swift swift-5 swift5 swiftui uikit
Last synced: 7 months ago
JSON representation
🔥 A Swifty solution for all things Firebase. Quickly implement Firestore and Authentication on iOS + macOS using Swift protocols and methods.
- Host: GitHub
- URL: https://github.com/Flowductive/easy-firebase
- Owner: Flowductive
- License: mit
- Archived: true
- Created: 2021-10-29T03:49:11.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-29T05:41:08.000Z (almost 2 years ago)
- Last Synced: 2024-10-06T01:46:10.918Z (over 1 year ago)
- Topics: authentication, cloud-messaging, firebase, firebase-auth, firebase-storage, firestore, ios, macos, push-notifications, sign-in-with-apple, sign-in-with-google, signinwithapple, signinwithgoogle, storage, swift, swift-5, swift5, swiftui, uikit
- Language: Swift
- Homepage:
- Size: 81.9 MB
- Stars: 76
- Watchers: 3
- Forks: 7
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
.png)
Firebase for iOS and macOS made easy.
🍏 Third-party authentication done in a single line of code
✉️ Send and receive Firestore documents in a snap
😀 Predefined user protocols with built-in features
🔥 Firebase solutions in one native Swift package
📘 Fully documented code with examples
***
⚠️ **Note:** This package is still under development and its contents are freely subject to change.
📚 **Ready to get started?** Check out our [complete wiki](https://github.com/Flowductive/easy-firebase/wiki) for detailed guides.




[](https://swiftpackageindex.com/Flowductive/easy-firebase)
[](https://swiftpackageindex.com/Flowductive/easy-firebase)
## What is EasyFirebase?
EasyFirebase is a Swift wrapper for all things Firebase. Save hours from implementing the Firebase code in your projects repeatedly. EasyFirebase makes document storage and retrieval easier by providing **intuitive protocols** for Firestore. EasyFirebase makes **authentication easier** with the EasyUser (subclassable) open class and simple one-line sign-in with Google and Apple. EasyFirebase is cross-platform and works with both iOS and macOS.
## Completed Features
- Firestore Support
- Built-in Document protocol [→](https://github.com/Flowductive/easy-firebase#built-in-document-protocol)
- Document storage [→](https://github.com/Flowductive/easy-firebase#document-storage)
- Document removal
- Document retrieval [→](https://github.com/Flowductive/easy-firebase#document-retrieval)
- ✨ NEW: Document updating [→](https://github.com/Flowductive/easy-firebase#document-updating)
- Update listeners [→](https://github.com/Flowductive/easy-firebase#update-listeners)
- Built-in cacheing [→](https://github.com/Flowductive/easy-firebase#built-in-cacheing)
- Easy linking [→](https://github.com/Flowductive/easy-firebase#easy-linking)
- Swifty querying [→](https://github.com/Flowductive/easy-firebase#swifty-querying)
- Authentication Support
- EasyUser protocol [→](https://github.com/Flowductive/easy-firebase#easy-user-protocol)
- Email auth [→](https://github.com/Flowductive/easy-firebase#email-auth)
- Sign In with Google [→](https://github.com/Flowductive/easy-firebase#sign-in-with-google)
- Sign In with Apple [→](https://github.com/Flowductive/easy-firebase#sign-in-with-apple)
- Built-in usernames [→](https://github.com/Flowductive/easy-firebase#built-in-usernames)
- Robust user management [→](https://github.com/Flowductive/easy-firebase#robust-user-management)
- Storage Support
- Data storage [→](https://github.com/Flowductive/easy-firebase#data-storage)
- Safe data overriding
- Data removal
- Data upload task visibility
- Cloud Messaging Support
- Built-in user notifications [→](https://github.com/Flowductive/easy-firebase#built-in-user-notifications)
- Built-in MessagingNotification protocol
- Built-in 3P notifications
- User notification settings
- Analytics Support
- Easily log events [→](https://github.com/Flowductive/easy-firebase#easily-log-events)
- Integrated user properties [→](https://github.com/Flowductive/easy-firebase#integrated-user-properties)
All the above features are **cross-platform** and are supported on both iOS and macOS.
⭐️ This means EasyFirebase is the quickest way to implement Sign In with Google on macOS! ⭐️
## Get Started
Add **EasyFirebase** to your project using Swift Package Manager:
```
https://github.com/Flowductive/easy-firebase
```
Import **EasyFirebase**:
```swift
import EasyFirebase
```
Configure at app launch:
```swift
// You don't need to call FirebaseApp.configure() when this is called!
EasyFirebase.configure()
```
## 🔥 Firestore Feature Showcase
### Built-in Document protocol
Save time writing model classes with the built-in `Document` protocol:
```swift
class Car: Document {
// These properties are inherited from Document
var id: String = UUID().uuidString
var dateCreated: Date = Date()
// Define your own custom properties
var make: String
var model: String
var year: Int
init(make: String, model: String, year: Int) {
// ...
}
}
```
### Document Storage
Store documents anywhere in your code:
```swift
var myCar = Car(make: "Toyota", model: "Corolla", year: 2017)
// Store the car instance in the 'car' collection in Firestore
myCar.set()
// Static method that does the same as above
EasyFirestore.Storage.set(myCar)
```
### Document Retrieval
Grab documents easily without needing to specify a collection name:
```swift
EasyFirestore.Retrieval.get(id: myCarID, ofType: Car.self) { car in
guard let car = car else { return }
self.myOtherCar = car
}
```
### Document Updating
Update fields remotely in Firestore without performing any reads.
```swift
// Append element to array
EasyFirestore.Updating.append(\.ingredients, with: "Cheese", in: pizzaDocument) { error in ... }
// Increment field
EasyFirestore.Updating.increment(\.pepperoniCount, by: 5, in: pizzaDocument)
// Remove elements from array
EasyFirestore.Updating.remove(\.ingredients, taking: ["Garlic", "Anchovies", "Pineapple"], from: pizzaDocument)
```
### Update Listeners
Grab documents and update the local instance when changed in Firestore:
```swift
EasyFirestore.Listening.listen(to: otherCarID, ofType: Car.self, key: "myCarListenerKey") { car in
// Updates when changed in Firestore
guard let car = car else { return }
self.myOtherCar = car
}
```
### Built-In Cacheing
EasyFirestore will automatically cache fetched documents locally and will use the cached doucments when retrieving to reduce your Firestore read count.
```swift
// EasyFirebase will automatically cache fetched objects for you, here is a manual example
EasyFirestore.Cacheing.register(myCar)
// Get locally cached objects instantly. Retrieving objects using EasyFirestore.Retrieval will grab cached objects if they exist
var cachedCar = EasyFirestore.Cacheing.grab(myCarID, fromType: Car.self)
```
### Easy Linking
Link child documents to an array of IDs in a parent document:
```swift
var car1 = Car(make: "Toyota", model: "Corolla", year: 2017)
var car2 = Car(make: "Honda", model: "Civic", year: 2019)
var dealership = Dealership(name: "Los Angeles Dealership")
// Set and assign the Toyota Corolla to the Los Angeles Dealership
car1.setAssign(toField: "cars", using: \.cars, in: dealership)
// Set and assign the Honda Civic to the Los Angeles Dealership
car2.set()
car2.assign(toField: "cars", using: \.cars, in: dealership)
```
### Swifty Querying
Easily query for documents:
```swift
EasyFirestore.Querying.where(\Car.make, .equals, "Toyota") { cars in
// Handle your queried documents here...
}
```
Use multiple conditions for queries; order and limit results:
```swift
EasyFirestore.Querying.where((\Car.year, .greaterEqualTo, 2010),
(\Car.model, .in, ["Corolla", "Camry"]),
order: .ascending,
limit: 5
) { cars in
// ...
}
```
## 🔑 Authentication Feature Showcase
### Easy User Protocol
Save time writing user classes with the built-in `EasyUser` open class:
```swift
class MyUser: EasyUser {
// EasyUser comes pre-built with these automatically updated properties
var lastSignon: Date
var displayName: String
var username: String
var email: String
var appVersion: String
var deviceToken: String?
var notifications: [MessagingNotification]
var disabledMessageCategories: [MessageCategory]
var progress: Int
var id: String
var dateCreated: Date
// Define your own custom properties
var cars: [Car.ID]
// ...
}
```
⚠️ **Note:** Be sure to read the [the wiki](https://github.com/Flowductive/easy-firebase/wiki/Get-Started-with-EasyAuth) to implement this properly!
### Email Auth
Authenticate with an email and password easily:
```swift
EasyAuth.createAccount(email: "easy.firebase@example.com", password: "76dp2[&y4;JLyu:F") { error in
if let error = error {
print(error.localizedDescription)
} else {
// Account created!
}
}
EasyAuth.signIn(email: "easy.firebase@example.com", password: "76dp2[&y4;JLyu:F") { error in
// ...
}
```
### Sign In with Google
Authenticate with Google:
```swift
// iOS
EasyAuth.signInWithGoogle(clientID: "xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") { error in
// ...
}
// macOS
EasyAuth.signInWithGoogle(clientID: "xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
secret: "GOCSPX-xxxxxxxxxxxxxxxxxxx-xxxxxxxx") { error in
// ...
}
```
### Sign In with Apple
Authenticate with Apple:
```swift
// iOS + macOS
EasyAuth.signInWithApple()
```
### Built-In Usernames
Generate unique usernames and update easily:
```swift
user.safelyUpdateUsername(to: "myNewUsername", ofUserType: MyUser.self) { error, suggestion in
if let error = error {
// ...
} else if let suggestion = suggestion {
// Username taken, provide the user with an available username suggestion.
} else {
// Success! Username changed.
}
}
```
### Robust User Management
Quickly update and manage `EasyAuth` users:
```swift
// Send a verfication email to the currently signed-in user
user.sendEmailVerification(completion: { error in })
// Upload and update the current user's profile photo
user.updatePhoto(with: myPhotoData, ofUserType: FUser.self, completion: { error in })
// Send the current user's password reset form to a specified email
user.sendPasswordReset(toEmail: "myResetEmail@example.com", completion: { error in })
// Update the current user's display name
user.updateDisplayName(to: "New_DisplayName", ofUserType: MyUser.self, completion: { error in })
// Update the current user's password
user.updatePassword(to: "newPassword", completion: { error in })
// Delete the current user
user.delete(ofUserType: MyUser.self, completion: { error in })
```
## 📦 Storage Feature Showcase
### Data Storage
Quickly assign data to Firebase Storage using a single line of code.
```swift
// Upload image data and get an associated URL
EasyStorage.put(imageData, to: StorageResource(id: user.id)) { url in }
// EasyStorage will automatically delete existing images matching the same ID (if in the same folder)
EasyStorage.put(imageData,to: StorageResource(id: user.id, folder: "myFolder"), progress: { updatedProgress in
// Update progress text label using updatedProgress
}, completion: { url in
// Handle the image's URL
})
```
## ☁️ Cloud Messaging Feature Showcase
### Built-in User Notifications
Easily send and notify other users without all the tedious setup. Just add a `serverKey` from [Firebase Console](https://console.firebase.google.com).
```swift
// Set your Server Key
EasyMessaging.serverKey = "xxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxx-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxx"
// Create the notification
let notification = MessagingNotification("Message body", from: me, in: "Test Category")
// Send the notification to the user
// Appends to the notifications property, unless the specified category is in the user's disabledMessageCategories
EasyMessaging.send(notification, to: you)
```
## 📊 Analytics Feature Showcase
### Easily Log Events
To log an event, you can use `EasyAnalytics`' static methods:
```swift
EasyAnalytics.log("food_eaten", data: [
"name": "Hot Dog",
"isHot": true
])
```
If you have a model that conforms to `AnalyticsLoggable`, you can log events using the model itself:
```swift
let hotdog = Food(name: "Hot Dog", temperature: 81)
EasyAnalytics.log("food_eaten", model: hotdog)
```
Alternatively, you can call the logging method from the model itself:
```swift
hotdog.log(key: "food_eaten")
```
### Integrated User Properties
Override the `analyticsProperties()` method to automatically update user properties on app launch:
```swift
struct MyUser: EasyUser {
// ...
var favoriteCar: String
func analyticsProperties() -> [String: String] {
return ["app_version": appVersion, "favorite_car": favoriteCar]
}
}
```
Manually update the user properties to Firebase Analytics:
```swift
myUser.updateAnalyticsUserProperties()
```