Ferno allows you to easily connect your Vapor project with your Firebase realtime database. It is built with the brand new Vapor 4. It gives you a nice and clean interface to interact with the Firebase Realtime REST API. It will automatically turn the response into your class/struct!
You will need:
In your Package.swift file, add the line
.package(url: "https://github.com/vapor-community/ferno.git", from: "0.6.0")
Also make sure you add Ferno
as a dependency
dependencies: [
.product(name: "Ferno", package: "ferno")
]
Ferno uses an access token to read and write to your database. First we will need to get your service account information.
Project Overview
Project settings
SERVICE ACCOUNTS
tabGENERATE NEW PRIVATE KEY
.json
file. You will now have access to the email and private key. You will pass those into the initialize during the next step.Register Ferno
as a Provider and import Ferno
. This is usually done in configure.swift
Project Overview
Project settings
SERVICE ACCOUNTS
tabFirebase Admin SDK
optionGenerate new private key
to download the json file.You can use the content of json file information to fill out the FernoDefaultConfiguration
or use the json file to preper the FernoServiceJsonConfiguration
.
import Ferno
let fernoConfiguration = FernoDefaultConfiguration(
basePath: "database-url",
email: "service-account-email",
privateKey: "private-key"
)
app.ferno.use(.default(fernoConfiguration))
If you prefer to use the Firebase ServiceAccount.json
follow the example below.
import Ferno
// option 1
let fernoConfiguration = try FernoServiceJsonConfiguration(json: Data)
// option 2
let fernoConfiguration = try FernoServiceJsonConfiguration(path: URL)
// option 3
let fernoConfiguration = FernoServiceJsonConfiguration(
type: String,
projectId: String,
privateKeyId: String,
privateKey: String,
clientEmail: String,
clientId: String,
authUri: String,
tokenUri: String,
authProviderX509CertUrl: String,
clientX509CertUrl: String,
universeDomain: String
)
app.ferno.use(.serviceAccountKey(fernoConfiguration))
There are some custom parameters to pass into functions. I want to go over all the parameters you will need to know.
In GET requests, you might want to query on your data. This is what [FernoQuery]
is for.
FernoQuery
is an enum with:
case shallow(Bool)
case orderBy(FernoValue)
case limitToFirst(FernoValue)
case limitToLast(FernoValue)
case startAt(FernoValue)
case endAt(FernoValue)
case equalTo(FernoValue)
These are all the possible queries that are allowed on Firebase according to the docs
shallow(Bool)
cannot be mixed with any other query parameters.orderBy(FernoValue)
in conjunction with enums 3-7
orderBy(FernoValue)
alone will just order the data returnedYou will notice most cases in FernoQuery
have a value of FernoValue
.
FernoValue
is just a wrapper for Bool, String, Int, Double, Float
. So you can just do .startAt(5)
and everything will work.
Just using shallow:
[.shallow(true)]
Filter data to only return data that matches "age": 21
:
[.orderBy("age"), .equalTo(21)]
Just orderBy(returns data in ascending order):
[.orderBy("age")]
There are 6 functions that allow you to interact with your Firebase realtime database.
There are four functions that allow you get your data.
app.ferno.retrieve(_ path: [String], queryItems: [FernoQuery] = [])
app.ferno.retrieve(_ path: String..., queryItems: [FernoQuery] = [])
app.ferno.retrieveMany(_ path: [String], queryItems: [FernoQuery] = [])
app.ferno.retrieveMany(_ path: String..., queryItems: [FernoQuery] = [])
The only difference between retrieve
and retrieveMany
is the return type.
retrieve
returns -> F
where F
is of type Decodable
retrieveMany
returns -> [String: F]
where F
is of type Decodable
and String
is the keystruct Developer: Content {
var name: String
var favLanguage: String
var age: Int
}
let developers: [String: Developer] = try await app.ferno.retrieveMany("developers")
let developer: Developer = try await app.ferno.retrieve(["developers", "dev1"])
Used to create a new entry in your database
app.ferno.create(_ path: [String], body: T) try await -> FernoChild
app.ferno.create(_ path: String..., body: T) try await -> FernoChild
body: T
is of type Content
.FernoChild
is a struct:struct FernoChild: Content {
var name: String
}
FernoChild
is returned, because the API request returns the key from the newly created child.let newDeveloper = Developer(name: "Elon", favLanguage: "Python", age: 46) // conforms to Content
let newDeveloperKey: FernoChild = try await app.ferno.create("developers", body: newDeveloper)
Used to delete an entry in your database
app.ferno.delete(_ path: [String]) try await -> Bool
app.ferno.delete(_ path: String...) try await -> Bool
let successfulDelete: Bool = try await app.ferno.delete(["developers", "dev-1"])
Update values at a specific location, but omitted values won't get removed
app.ferno.update(_ path: [String], body: T) try await -> T
app.ferno.update(_ path: String..., body: T) try await -> T
struct UpdateDeveloperName: Content {
var name: String
}
let newDeveloperName = UpdateDeveloperName(name: "Kimbal") //conforms to Content
let updatedDeveloperName: UpdateDeveloperName = try await app.ferno.update(["developers", newDeveloperKey.name], body: newDeveloper) //newDeveloperKey.name comes from the create method
Overwrite the current location with data you are passing in
client.ferno.overwrite(_ path: [String], body: T) try await -> T
client.ferno.overwrite(_ path: String..., body: T) try await -> T
struct LeadDeveloper: Content {
var name: String
var company: String
var age: Int
}
let leadDeveloper = LeadDeveloper(name: "Ashley", company: "Bio-Fit", age: 20)
let leadDevResponse: LeadDeveloper = try await app.ferno.overwrite(["developers", newDeveloperKey.name], body: leadDeveloper)
Currently, tests were written using an actual dummy Firebase realtime database. If you want to run all of the tests, you will need to create a dummy Firebase realtime database.
You need to go to Application+Testing.swift
and fill in the missing values based on your Firebase service account. Then you will be able to run tests.
This project is licensed under the MIT License - see the LICENSE.md file for details
link |
Stars: 69 |
Last commit: 26 weeks ago |
Full Changelog: https://github.com/vapor-community/ferno/compare/0.5.1...0.6.0
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics