Skip to content

Commit af5efdb

Browse files
authored
[storage] Simplify callback implementation (#13413)
1 parent 4883ced commit af5efdb

File tree

8 files changed

+51
-116
lines changed

8 files changed

+51
-116
lines changed

FirebaseStorage/Sources/Internal/StorageTokenAuthorizer.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class StorageTokenAuthorizer: NSObject, GTMSessionFetcherAuthorizer {
3737
request?.setValue(googleAppID, forHTTPHeaderField: "x-firebase-gmpid")
3838

3939
var tokenError: NSError?
40-
let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main
4140
let fetchTokenGroup = DispatchGroup()
4241
if let auth {
4342
fetchTokenGroup.enter()
@@ -101,19 +100,19 @@ class StorageTokenAuthorizer: NSObject, GTMSessionFetcherAuthorizer {
101100

102101
var userEmail: String?
103102

104-
let fetcherService: GTMSessionFetcherService
103+
let callbackQueue: DispatchQueue
105104
private let googleAppID: String
106105
private let auth: AuthInterop?
107106
private let appCheck: AppCheckInterop?
108107

109108
private let serialAuthArgsQueue = DispatchQueue(label: "com.google.firebasestorage.authorizer")
110109

111110
init(googleAppID: String,
112-
fetcherService: GTMSessionFetcherService,
111+
callbackQueue: DispatchQueue = DispatchQueue.main,
113112
authProvider: AuthInterop?,
114113
appCheck: AppCheckInterop?) {
115114
self.googleAppID = googleAppID
116-
self.fetcherService = fetcherService
115+
self.callbackQueue = callbackQueue
117116
auth = authProvider
118117
self.appCheck = appCheck
119118
}

FirebaseStorage/Sources/Storage.swift

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,7 @@ import FirebaseCore
123123
@objc public var uploadChunkSizeBytes: Int64 = .max
124124

125125
/// A `DispatchQueue` that all developer callbacks are fired on. Defaults to the main queue.
126-
@objc public var callbackQueue: DispatchQueue {
127-
get {
128-
ensureConfigured()
129-
guard let queue = fetcherService?.callbackQueue else {
130-
fatalError("Internal error: Failed to initialize fetcherService callbackQueue")
131-
}
132-
return queue
133-
}
134-
set(newValue) {
135-
ensureConfigured()
136-
fetcherService?.callbackQueue = newValue
137-
}
138-
}
126+
@objc public var callbackQueue: DispatchQueue = .main
139127

140128
/// Creates a `StorageReference` initialized at the root Firebase Storage location.
141129
/// - Returns: An instance of `StorageReference` referencing the root of the storage bucket.
@@ -317,7 +305,8 @@ import FirebaseCore
317305
private static func initFetcherServiceForApp(_ app: FirebaseApp,
318306
_ bucket: String,
319307
_ auth: AuthInterop?,
320-
_ appCheck: AppCheckInterop?)
308+
_ appCheck: AppCheckInterop?,
309+
_ callbackQueue: DispatchQueue)
321310
-> GTMSessionFetcherService {
322311
objc_sync_enter(fetcherServiceLock)
323312
defer { objc_sync_exit(fetcherServiceLock) }
@@ -334,7 +323,7 @@ import FirebaseCore
334323
fetcherService?.allowLocalhostRequest = true
335324
let authorizer = StorageTokenAuthorizer(
336325
googleAppID: app.options.googleAppID,
337-
fetcherService: fetcherService!,
326+
callbackQueue: callbackQueue,
338327
authProvider: auth,
339328
appCheck: appCheck
340329
)
@@ -390,7 +379,8 @@ import FirebaseCore
390379
guard fetcherService == nil else {
391380
return
392381
}
393-
fetcherService = Storage.initFetcherServiceForApp(app, storageBucket, auth, appCheck)
382+
fetcherService = Storage.initFetcherServiceForApp(app, storageBucket, auth, appCheck,
383+
callbackQueue)
394384
if usesEmulator {
395385
fetcherService?.allowLocalhostRequest = true
396386
fetcherService?.allowedInsecureSchemes = ["http"]

FirebaseStorage/Sources/StorageObservableTask.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,11 @@ import Foundation
168168

169169
func fire(handlers: [String: (StorageTaskSnapshot) -> Void],
170170
snapshot: StorageTaskSnapshot) {
171-
let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main
172171
objc_sync_enter(StorageObservableTask.self)
173172
let enumeration = handlers.enumerated()
174173
objc_sync_exit(StorageObservableTask.self)
175174
for (_, handler) in enumeration {
176-
callbackQueue.async {
175+
reference.storage.callbackQueue.async {
177176
handler.value(snapshot)
178177
}
179178
}

FirebaseStorage/Sources/StorageReference.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ import Foundation
206206
file: nil)
207207

208208
task.completionData = completion
209-
let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main
209+
let callbackQueue = storage.callbackQueue
210210

211211
task.observe(.success) { snapshot in
212212
let error = self.checkSizeOverflow(task: snapshot.task, maxSize: maxSize)
@@ -288,7 +288,7 @@ import Foundation
288288

289289
if let completion {
290290
task.completionURL = completion
291-
let callbackQueue = fetcherService.callbackQueue ?? DispatchQueue.main
291+
let callbackQueue = storage.callbackQueue
292292

293293
task.observe(.success) { snapshot in
294294
callbackQueue.async {

FirebaseStorage/Tests/Unit/StorageAuthorizerTests.swift

Lines changed: 39 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ class StorageAuthorizerTests: StorageTestHelpers {
4343
let fetchRequest = URLRequest(url: StorageTestHelpers().objectURL())
4444
fetcher = GTMSessionFetcher(request: fetchRequest)
4545

46-
fetcherService = GTMSessionFetcherService()
4746
auth = FIRAuthInteropFake(token: StorageTestAuthToken, userID: nil, error: nil)
4847
appCheck = FIRAppCheckFake()
4948
fetcher?.authorizer = StorageTokenAuthorizer(googleAppID: "dummyAppID",
50-
fetcherService: fetcherService!,
49+
callbackQueue: DispatchQueue.main,
5150
authProvider: auth, appCheck: appCheck)
5251
}
5352

@@ -60,130 +59,97 @@ class StorageAuthorizerTests: StorageTestHelpers {
6059
super.tearDown()
6160
}
6261

63-
func testSuccessfulAuth() {
64-
let expectation = self.expectation(description: #function)
62+
func testSuccessfulAuth() async throws {
6563
setFetcherTestBlock(with: 200) { fetcher in
6664
self.checkAuthorizer(fetcher: fetcher, trueFalse: true)
6765
}
68-
fetcher?.beginFetch { data, error in
69-
let headers = self.fetcher!.request?.allHTTPHeaderFields
70-
XCTAssertEqual(headers!["Authorization"], "Firebase \(self.StorageTestAuthToken)")
71-
expectation.fulfill()
72-
}
73-
waitForExpectation(test: self)
66+
let _ = try await fetcher?.beginFetch()
67+
let headers = fetcher!.request?.allHTTPHeaderFields
68+
XCTAssertEqual(headers!["Authorization"], "Firebase \(StorageTestAuthToken)")
7469
}
7570

76-
func testUnsuccessfulAuth() {
77-
let expectation = self.expectation(description: #function)
71+
func testUnsuccessfulAuth() async {
7872
let authError = NSError(domain: "FIRStorageErrorDomain",
7973
code: StorageErrorCode.unauthenticated.rawValue, userInfo: nil)
8074
let failedAuth = FIRAuthInteropFake(token: nil, userID: nil, error: authError)
8175
fetcher?.authorizer = StorageTokenAuthorizer(
8276
googleAppID: "dummyAppID",
83-
fetcherService: fetcherService!,
8477
authProvider: failedAuth,
8578
appCheck: nil
8679
)
8780
setFetcherTestBlock(with: 401) { fetcher in
8881
self.checkAuthorizer(fetcher: fetcher, trueFalse: false)
8982
}
90-
fetcher?.beginFetch { data, error in
91-
let headers = self.fetcher!.request?.allHTTPHeaderFields
92-
XCTAssertNil(headers)
93-
let nsError = error as? NSError
94-
XCTAssertEqual(nsError?.domain, "FIRStorageErrorDomain")
95-
XCTAssertEqual(nsError?.code, StorageErrorCode.unauthenticated.rawValue)
96-
XCTAssertEqual(nsError?.localizedDescription, "User is not authenticated, please " +
83+
do {
84+
let _ = try await fetcher?.beginFetch()
85+
} catch {
86+
let nsError = error as NSError
87+
XCTAssertEqual(nsError.domain, "FIRStorageErrorDomain")
88+
XCTAssertEqual(nsError.code, StorageErrorCode.unauthenticated.rawValue)
89+
XCTAssertEqual(nsError.localizedDescription, "User is not authenticated, please " +
9790
"authenticate using Firebase Authentication and try again.")
98-
expectation.fulfill()
9991
}
100-
waitForExpectation(test: self)
10192
}
10293

103-
func testSuccessfulUnauthenticatedAuth() {
104-
let expectation = self.expectation(description: #function)
105-
94+
func testSuccessfulUnauthenticatedAuth() async throws {
10695
// Simulate Auth not being included at all
10796
fetcher?.authorizer = StorageTokenAuthorizer(
10897
googleAppID: "dummyAppID",
109-
fetcherService: fetcherService!,
11098
authProvider: nil,
11199
appCheck: nil
112100
)
113101

114102
setFetcherTestBlock(with: 200) { fetcher in
115103
self.checkAuthorizer(fetcher: fetcher, trueFalse: false)
116104
}
117-
fetcher?.beginFetch { data, error in
118-
let headers = self.fetcher!.request?.allHTTPHeaderFields
119-
XCTAssertNil(headers!["Authorization"])
120-
XCTAssertNil(error)
121-
expectation.fulfill()
122-
}
123-
waitForExpectation(test: self)
105+
let _ = try await fetcher?.beginFetch()
106+
let headers = fetcher!.request?.allHTTPHeaderFields
107+
XCTAssertNil(headers!["Authorization"])
124108
}
125109

126-
func testSuccessfulAppCheckNoAuth() {
127-
let expectation = self.expectation(description: #function)
110+
func testSuccessfulAppCheckNoAuth() async throws {
128111
appCheck?.tokenResult = appCheckTokenSuccess!
129112

130113
// Simulate Auth not being included at all
131114
fetcher?.authorizer = StorageTokenAuthorizer(
132115
googleAppID: "dummyAppID",
133-
fetcherService: fetcherService!,
134116
authProvider: nil,
135117
appCheck: appCheck
136118
)
137119

138120
setFetcherTestBlock(with: 200) { fetcher in
139121
self.checkAuthorizer(fetcher: fetcher, trueFalse: false)
140122
}
141-
fetcher?.beginFetch { data, error in
142-
let headers = self.fetcher!.request?.allHTTPHeaderFields
143-
XCTAssertEqual(headers!["X-Firebase-AppCheck"], self.appCheckTokenSuccess?.token)
144-
XCTAssertNil(error)
145-
expectation.fulfill()
146-
}
147-
waitForExpectation(test: self)
123+
let _ = try await fetcher?.beginFetch()
124+
let headers = fetcher!.request?.allHTTPHeaderFields
125+
XCTAssertEqual(headers!["X-Firebase-AppCheck"], appCheckTokenSuccess?.token)
148126
}
149127

150-
func testSuccessfulAppCheckAndAuth() {
151-
let expectation = self.expectation(description: #function)
128+
func testSuccessfulAppCheckAndAuth() async throws {
152129
appCheck?.tokenResult = appCheckTokenSuccess!
153130

154131
setFetcherTestBlock(with: 200) { fetcher in
155132
self.checkAuthorizer(fetcher: fetcher, trueFalse: true)
156133
}
157-
fetcher?.beginFetch { data, error in
158-
let headers = self.fetcher!.request?.allHTTPHeaderFields
159-
XCTAssertEqual(headers!["Authorization"], "Firebase \(self.StorageTestAuthToken)")
160-
XCTAssertEqual(headers!["X-Firebase-AppCheck"], self.appCheckTokenSuccess?.token)
161-
XCTAssertNil(error)
162-
expectation.fulfill()
163-
}
164-
waitForExpectation(test: self)
134+
let _ = try await fetcher?.beginFetch()
135+
let headers = fetcher!.request?.allHTTPHeaderFields
136+
XCTAssertEqual(headers!["Authorization"], "Firebase \(StorageTestAuthToken)")
137+
XCTAssertEqual(headers!["X-Firebase-AppCheck"], appCheckTokenSuccess?.token)
165138
}
166139

167-
func testAppCheckError() {
168-
let expectation = self.expectation(description: #function)
140+
func testAppCheckError() async throws {
169141
appCheck?.tokenResult = appCheckTokenError!
170142

171143
setFetcherTestBlock(with: 200) { fetcher in
172144
self.checkAuthorizer(fetcher: fetcher, trueFalse: true)
173145
}
174-
fetcher?.beginFetch { data, error in
175-
let headers = self.fetcher!.request?.allHTTPHeaderFields
176-
XCTAssertEqual(headers!["Authorization"], "Firebase \(self.StorageTestAuthToken)")
177-
XCTAssertEqual(headers!["X-Firebase-AppCheck"], self.appCheckTokenError?.token)
178-
XCTAssertNil(error)
179-
expectation.fulfill()
180-
}
181-
waitForExpectation(test: self)
146+
let _ = try await fetcher?.beginFetch()
147+
let headers = fetcher!.request?.allHTTPHeaderFields
148+
XCTAssertEqual(headers!["Authorization"], "Firebase \(StorageTestAuthToken)")
149+
XCTAssertEqual(headers!["X-Firebase-AppCheck"], appCheckTokenError?.token)
182150
}
183151

184-
func testIsAuthorizing() {
185-
let expectation = self.expectation(description: #function)
186-
152+
func testIsAuthorizing() async throws {
187153
setFetcherTestBlock(with: 200) { fetcher in
188154
do {
189155
let authorizer = try XCTUnwrap(fetcher.authorizer)
@@ -192,16 +158,10 @@ class StorageAuthorizerTests: StorageTestHelpers {
192158
XCTFail("Failed to get authorizer: \(error)")
193159
}
194160
}
195-
fetcher?.beginFetch { data, error in
196-
XCTAssertNil(error)
197-
expectation.fulfill()
198-
}
199-
waitForExpectation(test: self)
161+
let _ = try await fetcher?.beginFetch()
200162
}
201163

202-
func testStopAuthorizingNoop() {
203-
let expectation = self.expectation(description: #function)
204-
164+
func testStopAuthorizingNoop() async throws {
205165
setFetcherTestBlock(with: 200) { fetcher in
206166
do {
207167
let authorizer = try XCTUnwrap(fetcher.authorizer)
@@ -214,18 +174,12 @@ class StorageAuthorizerTests: StorageTestHelpers {
214174
XCTFail("Failed to get authorizer: \(error)")
215175
}
216176
}
217-
fetcher?.beginFetch { data, error in
218-
XCTAssertNil(error)
219-
let headers = self.fetcher!.request?.allHTTPHeaderFields
220-
XCTAssertEqual(headers!["Authorization"], "Firebase \(self.StorageTestAuthToken)")
221-
expectation.fulfill()
222-
}
223-
waitForExpectation(test: self)
177+
let _ = try await fetcher?.beginFetch()
178+
let headers = fetcher!.request?.allHTTPHeaderFields
179+
XCTAssertEqual(headers!["Authorization"], "Firebase \(StorageTestAuthToken)")
224180
}
225181

226-
func testEmail() {
227-
let expectation = self.expectation(description: #function)
228-
182+
func testEmail() async throws {
229183
setFetcherTestBlock(with: 200) { fetcher in
230184
do {
231185
let authorizer = try XCTUnwrap(fetcher.authorizer)
@@ -234,11 +188,7 @@ class StorageAuthorizerTests: StorageTestHelpers {
234188
XCTFail("Failed to get authorizer: \(error)")
235189
}
236190
}
237-
fetcher?.beginFetch { data, error in
238-
XCTAssertNil(error)
239-
expectation.fulfill()
240-
}
241-
waitForExpectation(test: self)
191+
let _ = try await fetcher?.beginFetch()
242192
}
243193

244194
// MARK: Helpers

FirebaseStorage/Tests/Unit/StorageDeleteTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class StorageDeleteTests: StorageTestHelpers {
2727
fetcherService = GTMSessionFetcherService()
2828
fetcherService?.authorizer = StorageTokenAuthorizer(
2929
googleAppID: "dummyAppID",
30-
fetcherService: fetcherService!,
3130
authProvider: nil,
3231
appCheck: nil
3332
)

FirebaseStorage/Tests/Unit/StorageGetMetadataTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class StorageGetMetadataTests: StorageTestHelpers {
2727
fetcherService = GTMSessionFetcherService()
2828
fetcherService?.authorizer = StorageTokenAuthorizer(
2929
googleAppID: "dummyAppID",
30-
fetcherService: fetcherService!,
3130
authProvider: nil,
3231
appCheck: nil
3332
)

FirebaseStorage/Tests/Unit/StorageListTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class StorageListTests: StorageTestHelpers {
2727
fetcherService = GTMSessionFetcherService()
2828
fetcherService?.authorizer = StorageTokenAuthorizer(
2929
googleAppID: "dummyAppID",
30-
fetcherService: fetcherService!,
3130
authProvider: nil,
3231
appCheck: nil
3332
)

0 commit comments

Comments
 (0)