Skip to content

Commit 84f28c1

Browse files
authored
Fixed DispatchGroup’s Excessive Wait in FunctionsContext (#13887)
1 parent 26841da commit 84f28c1

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

FirebaseFunctions/Sources/Internal/FunctionsContext.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,17 @@ struct FunctionsContextProvider {
6666
dispatchGroup.enter()
6767

6868
if options?.requireLimitedUseAppCheckTokens == true {
69-
appCheck.getLimitedUseToken? { tokenResult in
70-
// Send only valid token to functions.
71-
if tokenResult.error == nil {
72-
limitedUseAppCheckToken = tokenResult.token
69+
// `getLimitedUseToken(completion:)` is an optional protocol method.
70+
// If it’s not implemented, we still need to leave the dispatch group.
71+
if let limitedUseTokenClosure = appCheck.getLimitedUseToken {
72+
limitedUseTokenClosure { tokenResult in
73+
// Send only valid token to functions.
74+
if tokenResult.error == nil {
75+
limitedUseAppCheckToken = tokenResult.token
76+
}
77+
dispatchGroup.leave()
7378
}
79+
} else {
7480
dispatchGroup.leave()
7581
}
7682
} else {

FirebaseFunctions/Tests/Unit/ContextProviderTests.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ class ContextProviderTests: XCTestCase {
107107
waitForExpectations(timeout: 0.1)
108108
}
109109

110+
func testContextWithAppCheckWithoutOptionalMethods() {
111+
let appCheck = AppCheckFakeWithoutOptionalMethods(tokenResult: appCheckTokenSuccess)
112+
let provider = FunctionsContextProvider(auth: nil, messaging: nil, appCheck: appCheck)
113+
let expectation =
114+
expectation(description: "Verify non-implemented method for limited-use tokens")
115+
provider.getContext(options: .init(requireLimitedUseAppCheckTokens: true)) { context, error in
116+
XCTAssertNotNil(context)
117+
XCTAssertNil(error)
118+
XCTAssertNil(context.authToken)
119+
XCTAssertNil(context.fcmToken)
120+
XCTAssertNil(context.appCheckToken)
121+
// If the method for limited-use tokens is not implemented, the value should be `nil`:
122+
XCTAssertNil(context.limitedUseAppCheckToken)
123+
expectation.fulfill()
124+
}
125+
// Importantly, `getContext(options:_:)` must still finish in a timely manner:
126+
waitForExpectations(timeout: 0.1)
127+
}
128+
110129
func testAllContextsAvailableSuccess() {
111130
appCheckFake.tokenResult = appCheckTokenSuccess
112131
let auth = FIRAuthInteropFake(token: "token", userID: "userID", error: nil)
@@ -149,3 +168,21 @@ class ContextProviderTests: XCTestCase {
149168
waitForExpectations(timeout: 0.1)
150169
}
151170
}
171+
172+
// MARK: - Utilities
173+
174+
private class AppCheckFakeWithoutOptionalMethods: NSObject, AppCheckInterop {
175+
let tokenResult: FIRAppCheckTokenResultInterop
176+
177+
init(tokenResult: FIRAppCheckTokenResultInterop) {
178+
self.tokenResult = tokenResult
179+
}
180+
181+
func getToken(forcingRefresh: Bool, completion handler: @escaping AppCheckTokenHandlerInterop) {
182+
handler(tokenResult)
183+
}
184+
185+
func tokenDidChangeNotificationName() -> String { "AppCheckFakeTokenDidChangeNotification" }
186+
func notificationTokenKey() -> String { "AppCheckFakeTokenNotificationKey" }
187+
func notificationAppNameKey() -> String { "AppCheckFakeAppNameNotificationKey" }
188+
}

SharedTestUtilities/AppCheckFake/FIRAppCheckFake.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ - (void)getLimitedUseTokenWithCompletion:(FIRAppCheckTokenHandlerInterop)handler
4545
}
4646

4747
- (nonnull NSString *)notificationAppNameKey {
48-
return @"FakeAppCheckTokenDidChangeNotification";
48+
return @"AppCheckFakeAppNameNotificationKey";
4949
}
5050

5151
- (nonnull NSString *)notificationTokenKey {
52-
return @"FakeTokenNotificationKey";
52+
return @"AppCheckFakeTokenNotificationKey";
5353
}
5454

5555
- (nonnull NSString *)tokenDidChangeNotificationName {
56-
return @"FakeAppCheckTokenDidChangeNotification";
56+
return @"AppCheckFakeTokenDidChangeNotification";
5757
}
5858

5959
@end

0 commit comments

Comments
 (0)