Skip to content

Commit aea5e89

Browse files
mortenbekditlevsenpaulb777
authored andcommitted
[WIP] FirebaseFunctionsSwift (#8854)
1 parent e9252d2 commit aea5e89

File tree

3 files changed

+695
-0
lines changed

3 files changed

+695
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import Foundation
18+
import FirebaseFunctions
19+
import FirebaseSharedSwift
20+
21+
public extension Functions {
22+
/**
23+
* Creates a reference to the Callable HTTPS trigger with the given name, the type of an `Encodable`
24+
* request and the type of a `Decodable` response.
25+
*
26+
* - Parameter name: The name of the Callable HTTPS trigger
27+
* - Parameter requestType: The type of the `Encodable` entity to use for requests to this `Callable`
28+
* - Parameter responseType: The type of the `Decodable` entity to use for responses from this `Callable`
29+
*/
30+
func httpsCallable<Request: Encodable,
31+
Response: Decodable>(_ name: String,
32+
requestType: Request.Type,
33+
responseType: Response.Type,
34+
encoder: StructureEncoder = StructureEncoder(),
35+
decoder: StructureDecoder = StructureDecoder())
36+
-> Callable<Request, Response> {
37+
return Callable(callable: httpsCallable(name), encoder: encoder, decoder: decoder)
38+
}
39+
}
40+
41+
/**
42+
* A `Callable` is reference to a particular Callable HTTPS trigger in Cloud Functions.
43+
*/
44+
public struct Callable<Request: Encodable, Response: Decodable> {
45+
/**
46+
* The timeout to use when calling the function. Defaults to 60 seconds.
47+
*/
48+
public var timeoutInterval: TimeInterval {
49+
get {
50+
callable.timeoutInterval
51+
}
52+
set {
53+
callable.timeoutInterval = newValue
54+
}
55+
}
56+
57+
enum CallableError: Error {
58+
case internalError
59+
}
60+
61+
private let callable: HTTPSCallable
62+
private let encoder: StructureEncoder
63+
private let decoder: StructureDecoder
64+
65+
init(callable: HTTPSCallable, encoder: StructureEncoder, decoder: StructureDecoder) {
66+
self.callable = callable
67+
self.encoder = encoder
68+
self.decoder = decoder
69+
}
70+
71+
/**
72+
* Executes this Callable HTTPS trigger asynchronously.
73+
*
74+
* The data passed into the trigger must be of the generic `Request` type:
75+
*
76+
* The request to the Cloud Functions backend made by this method automatically includes a
77+
* Firebase Instance ID token to identify the app instance. If a user is logged in with Firebase
78+
* Auth, an auth ID token for the user is also automatically included.
79+
*
80+
* Firebase Instance ID sends data to the Firebase backend periodically to collect information
81+
* regarding the app instance. To stop this, see `[FIRInstanceID deleteIDWithHandler:]`. It
82+
* resumes with a new Instance ID the next time you call this method.
83+
*
84+
* - Parameter data: Parameters to pass to the trigger.
85+
* - Parameter completion: The block to call when the HTTPS request has completed.
86+
*
87+
* - Throws: An error if any value throws an error during encoding.
88+
*/
89+
public func call(_ data: Request,
90+
completion: @escaping (Result<Response, Error>)
91+
-> Void) throws {
92+
let encoded = try encoder.encode(data)
93+
94+
callable.call(encoded) { result, error in
95+
do {
96+
if let result = result {
97+
let decoded = try decoder.decode(Response.self, from: result.data)
98+
completion(.success(decoded))
99+
} else if let error = error {
100+
completion(.failure(error))
101+
} else {
102+
completion(.failure(CallableError.internalError))
103+
}
104+
} catch {
105+
completion(.failure(error))
106+
}
107+
}
108+
}
109+
110+
#if compiler(>=5.5) && canImport(_Concurrency)
111+
/**
112+
* Executes this Callable HTTPS trigger asynchronously.
113+
*
114+
* The data passed into the trigger must be of the generic `Request` type:
115+
*
116+
* The request to the Cloud Functions backend made by this method automatically includes a
117+
* Firebase Instance ID token to identify the app instance. If a user is logged in with Firebase
118+
* Auth, an auth ID token for the user is also automatically included.
119+
*
120+
* Firebase Instance ID sends data to the Firebase backend periodically to collect information
121+
* regarding the app instance. To stop this, see `[FIRInstanceID deleteIDWithHandler:]`. It
122+
* resumes with a new Instance ID the next time you call this method.
123+
*
124+
* - Parameter data: The `Request` representing the data to pass to the trigger.
125+
*
126+
* - Throws: An error if any value throws an error during encoding.
127+
* - Throws: An error if any value throws an error during decoding.
128+
* - Throws: An error if the callable fails to complete
129+
*
130+
* - Returns: The decoded `Response` value
131+
*/
132+
@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
133+
public func call(_ data: Request,
134+
encoder: StructureEncoder = StructureEncoder(),
135+
decoder: StructureDecoder =
136+
StructureDecoder()) async throws -> Response {
137+
let encoded = try encoder.encode(data)
138+
let result = try await callable.call(encoded)
139+
return try decoder.decode(Response.self, from: result.data)
140+
}
141+
#endif
142+
}

0 commit comments

Comments
 (0)