Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

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: 30 days ago
JSON representation

🔥 A Swifty solution for all things Firebase. Quickly implement Firestore and Authentication on iOS + macOS using Swift protocols and methods.

Awesome Lists containing this project

README

        

![Social Preview](./Assets/Social%20Preview%20(640).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.

![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/Flowductive/easy-firebase?label=version)
![GitHub Release Date](https://img.shields.io/github/release-date/Flowductive/easy-firebase?label=latest%20release)
![GitHub issues](https://img.shields.io/github/issues/Flowductive/easy-firebase)
![GitHub pull requests](https://img.shields.io/github/issues-pr/Flowductive/easy-firebase)

[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FFlowductive%2Feasy-firebase%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Flowductive/easy-firebase)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FFlowductive%2Feasy-firebase%2Fbadge%3Ftype%3Dplatforms)](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: "[email protected]", password: "76dp2[&y4;JLyu:F") { error in
if let error = error {
print(error.localizedDescription)
} else {
// Account created!
}
}

EasyAuth.signIn(email: "[email protected]", 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: "[email protected]", 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()
```