Swiftpack.co -  fummicc1/EasyFirebaseSwift as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
fummicc1/EasyFirebaseSwift
An Easy Firebase (Auth / Firestore) Library written in Swift.
.package(url: "https://github.com/fummicc1/EasyFirebaseSwift.git", from: "v1.3.1")

EasyFirebaseSwift

An Easy Firebase (Auth / Firestore) Library written in Swift.

Installation

Supporting SwiftPackageManager (SPM).

.package(url: "https://github.com/fummicc1/EasyFirebaseSwift", .upToNextMajor(from: "1.3.0"))

Usage

Model

First of all, create Model layer inheriting FirestoreModel protocol.


import EasyFirebaseSwift
import FirebaseFirestoreSwift
import FirebaseFirestore

struct Model: FirestoreModel {

    // - MARK : Necessary
    // the identifier to use when we observe single document within this model's collection.
    static var singleIdentifier: String = "model"
    
    // the identifier to use when we observe collection of this model.
    static var arrayIdentifier: String = "models"
    
    // collectionName corresponding to Firestore's collection schema.
    static var collectionName: String = "models"
    
    // To use PropertyWrapper such as @DocumentID, @ServerTimestamp, we need to import FirebaseFirestoreSwift.
    @DocumentID
    var ref: DocumentReference?
    
    @ServerTimestamp
    var createdAt: Timestamp?
    
    @ServerTimestamp
    var updatedAt: Timestamp?
    
    // - MARK : Custom property
    
    var message: String
}

Create

Create can be used like the following.

let client = FirestoreClient()

// Note: - new model must guarantee `createdAt`, `updatedAt` and `ref` are nil.
let model = Model(ref: nil, createdAt: nil, updatedAt: nil, message: "Test")

client.create(model) { reference in
    model.ref = reference
} failure: { error in
    print(error)
}

Update

Update can be used in this way.

let client = FirestoreClient()

// In this case, we fetch an exsisting data from Firestore.
client.get(uid: "example_1234567890") { model in
    var model = model
    model.message = "Update Test"

    // Note: - updated model must guarantee `createdAt`, `updatedAt` and `ref` are NOT nil.
    client.update(model) { reference in
        model.ref = reference
    } failure: { error in
        print(error)
    }
} failure: { error in
    print(error)
}

Read

If we want to get snapshots once, we should use get method, on the other hand, if we want to fetch the latest data whenever database is updated, we should use listen method.

Get

get is used like the following.

Note: It is necessary that we specify the type of reponse model by giving concrete type at closure parameter like the following.

Collection (Multiple Documents)

client.get(
    filter: [],
    order: [],
    limit: nil
) { (models: [Model]) in // Here, we need to specify concrete type at parameter of closure.
    for model in models {
        print(model.message)
    }
} failure: { error in
    print(error)
}

Single Document

client.get(uid: "1234567890") { (model: Model) in
    print(model.message)
} failure: { error in
    print(error)
}

Listen(Snapshot)

We can achieve both single observation and query observation of a certain collection at the same time!

listen also specifies which model we want by giving concrete type at closure parameter like the following.

Collection (Multiple Documents)

client.listen(
    filter: [],
    order: [],
    limit: nil
) { (models: [Model]) in // Here, we need to specify concrete type at parameter of closure.
    for model in models {
        print(model.message)
    }
} failure: { error in
    print(error)
}

Single Document

client.listen(uid: "1234567890") { (model: Model) in
    print(model.message)
} failure: { error in
    print(error)
}

Combine

Supporting Combine!

See example to check the usage.

// MARK: Combine

// Create
model.publisher(for: .create).sink { error in
    print(error)
} receiveValue: { }
.store(in: &cancellables)
        
// Get
let ref = Firestore.firestore().collection("models").document("sample")
Model.publisher(for: .get(ref: ref)).sink { completion in
    switch completion {
    case .failure(let error):
        print(error)
    case .finished:
        break
    }
} receiveValue: { model in
    print(model.message)
}
.store(in: &cancellables)

Contributing

Pull requests, bug reports and feature requests are welcome 🚀

GitHub

link
Stars: 2
Last commit: Yesterday

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

Fix minor bugs
3 weeks ago
  • Accept null for FilterValue

↓ possible to filter with nil.

FirestoreFilterEqualModel(fieldPath: "field_name", value: nil)
  • Add documentId parameter in creating model

  • Fix: write method for SubCollectionModel cannot set new document in the correct path.

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API