Skip to content

Instantly share code, notes, and snippets.

@ryanmeisters
Created October 27, 2019 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanmeisters/657297a3418e540c7a2eac40c0b0b29b to your computer and use it in GitHub Desktop.
Save ryanmeisters/657297a3418e540c7a2eac40c0b0b29b to your computer and use it in GitHub Desktop.
import Foundation
import ReactiveSwift
struct VoidResult: Codable {}
enum FunctionServiceError: Error {
case encodingError(_ error: Error)
case decodingError(_ error: Error)
case functonCallError(_ error: FunctionsError)
case error(_ error: Error)
case noData
}
struct FirebaseFunctionService {
private let functions = App.current.firebaseContainer.functions
func get<ResourceType: FunctionResource>(_ resource: ResourceType) -> SignalProducer<ResourceType.ResultType, FunctionServiceError> {
do {
let data = try JSONSerialization.jsonObject(with: try JSONEncoder().encode(resource)) as? [String: Any]
return functions.reactive.call(ResourceType.functionName, data: data)
.mapError { FunctionServiceError.functonCallError($0) }
.attemptMap { res -> Result<ResourceType.ResultType, FunctionServiceError> in
do {
let data = try JSONSerialization.data(withJSONObject: res)
let decoder = JSONDecoder.withFirestoreDateParsing
let decoded = try decoder.decode(ResourceType.ResultType.self, from: data)
return .success(decoded)
} catch let e as DecodingError {
// swiftformat:disable:next redundantReturn
return .failure(.decodingError(e))
} catch {
return .failure(.error(error))
}
}
} catch {
return .init(error: .encodingError(error))
}
}
}
extension JSONDecoder {
static var withFirestoreDateParsing: JSONDecoder {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(dateStrategy)
return decoder
}
static func dateStrategy(_ decoder: Decoder) throws -> Date {
let container = try decoder.singleValueContainer()
let val = try container.decode([String: Int].self)
if let seconds = val["_seconds"] {
return Date(timeIntervalSince1970: Double(seconds))
}
return Date()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment