Skip to content

Commit 2385785

Browse files
maksymmalyhinmikegerpaulb777
authored
Release 7.1.0 cherry picks (#6917)
* FCM: Fix crash on iOS 14 when multiple app delegate completion methods are called (#6863) * Fix crash on iOS 14 when multiple completion methods are called * Fixed lint * Addressed the PR comments & implemented unit tests * Reverted auto-extracted method * Re-organized tests * Added completion handler for FIRAuth * Manifest: GDT 8.0.1 * Update Changelogs for 7.1.0 (#6913) * Changelogs Co-authored-by: Mike Gerasimenko <[email protected]> Co-authored-by: Paul Beusterien <[email protected]>
1 parent 648ebdf commit 2385785

File tree

11 files changed

+170
-10
lines changed

11 files changed

+170
-10
lines changed

Crashlytics/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Unreleased
1+
# v7.1.0
22
- [fixed] Fixed an issue where symbol uploads would fail when there are spaces in the project path, particularly in Unity builds (#6789).
33
- [changed] Added additional logging when settings requests fail with a 404 status to help customers debug onboarding issues (#6847).
44

FirebaseAuth/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 7.1.0
2+
- [fixed] Fixed completion handler issue in `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` method. (#6863)
3+
14
# 7.0.0
25
- [removed] Remove deprecated APIs `dataForKey`,`fetchProvidersForEmail:completion`, `signInAndRetrieveDataWithCredential:completion`, `reauthenticateAndRetrieveDataWithCredential:completion`, `linkAndRetrieveDataWithCredential:completion`. (#6607)
36
- [added] Add support for the auth emulator. (#6624)

FirebaseAuth/Sources/Auth/FIRAuth.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,7 @@ - (void)application:(UIApplication *)application
14991499
didReceiveRemoteNotification:(NSDictionary *)userInfo
15001500
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
15011501
[self canHandleNotification:userInfo];
1502+
completionHandler(UIBackgroundFetchResultNoData);
15021503
}
15031504

15041505
// iOS 10 deprecation

FirebaseMessaging/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
# unreleased -- v.7.0.0
1+
# 2020-11 -- v7.1.0
2+
- [fixed] Fixed completion handler issue in `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` method. (#6863)
3+
4+
# 2020-10 -- v7.0.0
25
- [changed] Remove the deprecated FCM direct channel API and Upstream send API. (#6430)
36
- [changed] The `messaging:didReceiveRegistrationToken:` should be able to return a null token. Update the API parameter fcmToken to be nullable. (#5339)
47
- [fixed] Fixed an issue that downloading an image failed when there's no extension in the file name but MIME type is set. (#6590)

FirebaseMessaging/Sources/FIRMessagingRemoteNotificationsProxy.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ - (void)application:(UIApplication *)application
397397
didReceiveRemoteNotification:(NSDictionary *)userInfo
398398
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
399399
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
400+
completionHandler(UIBackgroundFetchResultNoData);
400401
}
401402

402403
- (void)application:(UIApplication *)application

Firestore/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Unreleased (v7.0.1)
1+
# v7.1.0
22
- [changed] Added the original query data to error messages for Queries that
33
cannot be deserizialized.
44
- [fixed] Remove explicit MobileCoreServices library linkage from podspec

GoogleDataTransport/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Unreleased
1+
# v8.0.1
22
- Remove `GCC_TREAT_WARNINGS_AS_ERRORS` from the podspec.
33
- Reduce pre-main startup time footprint. (#6855)
44

GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
2222
#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
2323

24+
#import <dispatch/group.h>
2425
#import <objc/runtime.h>
2526

2627
// Implementations need to be typed before calling the implementation directly to cast the
@@ -882,24 +883,72 @@ - (void)application:(GULApplication *)application
882883
didReceiveRemoteNotificationWithCompletionIMP =
883884
[didReceiveRemoteNotificationWithCompletionIMPPointer pointerValue];
884885

886+
dispatch_group_t __block callbackGroup = dispatch_group_create();
887+
NSMutableArray<NSNumber *> *__block fetchResults = [NSMutableArray array];
888+
889+
void (^localCompletionHandler)(UIBackgroundFetchResult) =
890+
^void(UIBackgroundFetchResult fetchResult) {
891+
[fetchResults addObject:[NSNumber numberWithInt:(int)fetchResult]];
892+
dispatch_group_leave(callbackGroup);
893+
};
894+
885895
// Notify interceptors.
886896
[GULAppDelegateSwizzler
887897
notifyInterceptorsWithMethodSelector:methodSelector
888898
callback:^(id<GULApplicationDelegate> interceptor) {
899+
dispatch_group_enter(callbackGroup);
900+
889901
NSInvocation *invocation = [GULAppDelegateSwizzler
890902
appDelegateInvocationForSelector:methodSelector];
891903
[invocation setTarget:interceptor];
892904
[invocation setSelector:methodSelector];
893905
[invocation setArgument:(void *)(&application) atIndex:2];
894906
[invocation setArgument:(void *)(&userInfo) atIndex:3];
895-
[invocation setArgument:(void *)(&completionHandler) atIndex:4];
907+
[invocation setArgument:(void *)(&localCompletionHandler)
908+
atIndex:4];
896909
[invocation invoke];
897910
}];
898911
// Call the real implementation if the real App Delegate has any.
899912
if (didReceiveRemoteNotificationWithCompletionIMP) {
913+
dispatch_group_enter(callbackGroup);
914+
900915
didReceiveRemoteNotificationWithCompletionIMP(self, methodSelector, application, userInfo,
901-
completionHandler);
916+
localCompletionHandler);
902917
}
918+
919+
dispatch_group_notify(callbackGroup, dispatch_get_main_queue(), ^() {
920+
BOOL allFetchesFailed = YES;
921+
BOOL anyFetchHasNewData = NO;
922+
923+
for (NSNumber *oneResult in fetchResults) {
924+
UIBackgroundFetchResult result = oneResult.intValue;
925+
926+
switch (result) {
927+
case UIBackgroundFetchResultNoData:
928+
allFetchesFailed = NO;
929+
break;
930+
case UIBackgroundFetchResultNewData:
931+
allFetchesFailed = NO;
932+
anyFetchHasNewData = YES;
933+
break;
934+
case UIBackgroundFetchResultFailed:
935+
936+
break;
937+
}
938+
}
939+
940+
UIBackgroundFetchResult finalFetchResult = UIBackgroundFetchResultNoData;
941+
942+
if (allFetchesFailed) {
943+
finalFetchResult = UIBackgroundFetchResultFailed;
944+
} else if (anyFetchHasNewData) {
945+
finalFetchResult = UIBackgroundFetchResultNewData;
946+
} else {
947+
finalFetchResult = UIBackgroundFetchResultNoData;
948+
}
949+
950+
completionHandler(finalFetchResult);
951+
});
903952
}
904953
#endif // !TARGET_OS_WATCH && !TARGET_OS_OSX
905954

GoogleUtilities/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 7.1.0 -- Unreleased
22
- Added `NSURLSession` promise extension. (#6753)
33
- `ios_on_mac` option added to `GULAppEnvironmentUtil.applePlatform()`. (#6799)
4+
- Fixed completion handler issue in `GULAppDelegateSwizzler` for
5+
`application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` method. (#6863)
46

57
# 7.0.0
68
- All APIs are now public. All CocoaPods private headers are transitioned to public. Note that

GoogleUtilities/Tests/Unit/Swizzler/GULAppDelegateSwizzlerTest.m

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,12 +1065,12 @@ - (void)testApplicationDidReceiveRemoteNotificationWithCompletionIsInvokedOnInte
10651065
id interceptor = OCMProtocolMock(@protocol(GULApplicationDelegate));
10661066
OCMExpect([interceptor application:application
10671067
didReceiveRemoteNotification:notification
1068-
fetchCompletionHandler:completion]);
1068+
fetchCompletionHandler:[OCMArg isNotNil]]);
10691069

10701070
id interceptor2 = OCMProtocolMock(@protocol(GULApplicationDelegate));
10711071
OCMExpect([interceptor2 application:application
10721072
didReceiveRemoteNotification:notification
1073-
fetchCompletionHandler:completion]);
1073+
fetchCompletionHandler:[OCMArg isNotNil]]);
10741074

10751075
GULTestAppDelegate *testAppDelegate = [[GULTestAppDelegate alloc] init];
10761076
OCMStub([self.mockSharedApplication delegate]).andReturn(testAppDelegate);
@@ -1087,7 +1087,108 @@ - (void)testApplicationDidReceiveRemoteNotificationWithCompletionIsInvokedOnInte
10871087

10881088
XCTAssertEqual(testAppDelegate.application, application);
10891089
XCTAssertEqual(testAppDelegate.remoteNotification, notification);
1090-
XCTAssertEqual(testAppDelegate.remoteNotificationCompletionHandler, completion);
1090+
}
1091+
1092+
- (void)verifyCompletionCalledForObserverResult:(UIBackgroundFetchResult)observerResult1
1093+
anotherObserverResult:(UIBackgroundFetchResult)observerResult2
1094+
swizzledResult:(UIBackgroundFetchResult)swizzledResult
1095+
expecredResult:(UIBackgroundFetchResult)expectedResult {
1096+
NSDictionary *notification = @{};
1097+
GULApplication *application = [GULApplication sharedApplication];
1098+
1099+
XCTestExpectation *completionExpectation =
1100+
[[XCTestExpectation alloc] initWithDescription:@"Completion called once"];
1101+
1102+
void (^completion)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult result) {
1103+
XCTAssertEqual(result, expectedResult);
1104+
[completionExpectation fulfill];
1105+
};
1106+
1107+
void (^onDidReceiveRemoteNotification1)(NSInvocation *invocation) = ^(NSInvocation *invocation) {
1108+
void __unsafe_unretained (^localCompletionHandler)(UIBackgroundFetchResult) = nil;
1109+
[invocation getArgument:(void *)(&localCompletionHandler) atIndex:4];
1110+
XCTAssertNotNil(localCompletionHandler);
1111+
localCompletionHandler(observerResult1);
1112+
};
1113+
1114+
id interceptor = OCMProtocolMock(@protocol(GULApplicationDelegate));
1115+
OCMExpect([interceptor application:application
1116+
didReceiveRemoteNotification:notification
1117+
fetchCompletionHandler:[OCMArg isNotNil]])
1118+
.andDo(onDidReceiveRemoteNotification1);
1119+
1120+
void (^onDidReceiveRemoteNotification2)(NSInvocation *invocation) = ^(NSInvocation *invocation) {
1121+
void __unsafe_unretained (^localCompletionHandler)(UIBackgroundFetchResult) = nil;
1122+
[invocation getArgument:(void *)(&localCompletionHandler) atIndex:4];
1123+
XCTAssertNotNil(localCompletionHandler);
1124+
localCompletionHandler(observerResult2);
1125+
};
1126+
1127+
id interceptor2 = OCMProtocolMock(@protocol(GULApplicationDelegate));
1128+
OCMExpect([interceptor2 application:application
1129+
didReceiveRemoteNotification:notification
1130+
fetchCompletionHandler:[OCMArg isNotNil]])
1131+
.andDo(onDidReceiveRemoteNotification2);
1132+
1133+
GULTestAppDelegate *testAppDelegate = [[GULTestAppDelegate alloc] init];
1134+
OCMStub([self.mockSharedApplication delegate]).andReturn(testAppDelegate);
1135+
[GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods];
1136+
1137+
[GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor];
1138+
[GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor2];
1139+
1140+
[testAppDelegate application:application
1141+
didReceiveRemoteNotification:notification
1142+
fetchCompletionHandler:completion];
1143+
testAppDelegate.remoteNotificationCompletionHandler(swizzledResult);
1144+
OCMVerifyAll(interceptor);
1145+
OCMVerifyAll(interceptor2);
1146+
[self waitForExpectations:@[ completionExpectation ] timeout:0.1];
1147+
}
1148+
1149+
- (void)testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce {
1150+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultNoData
1151+
anotherObserverResult:UIBackgroundFetchResultNoData
1152+
swizzledResult:UIBackgroundFetchResultNoData
1153+
expecredResult:UIBackgroundFetchResultNoData];
1154+
}
1155+
1156+
- (void)
1157+
testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce_HandleFailedState {
1158+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultFailed
1159+
anotherObserverResult:UIBackgroundFetchResultFailed
1160+
swizzledResult:UIBackgroundFetchResultFailed
1161+
expecredResult:UIBackgroundFetchResultFailed];
1162+
}
1163+
1164+
- (void)testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce_NoData {
1165+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultNoData
1166+
anotherObserverResult:UIBackgroundFetchResultFailed
1167+
swizzledResult:UIBackgroundFetchResultFailed
1168+
expecredResult:UIBackgroundFetchResultNoData];
1169+
}
1170+
- (void)
1171+
testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce_HandleNewDataState_OthersFailed {
1172+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultNewData
1173+
anotherObserverResult:UIBackgroundFetchResultFailed
1174+
swizzledResult:UIBackgroundFetchResultFailed
1175+
expecredResult:UIBackgroundFetchResultNewData];
1176+
}
1177+
1178+
- (void)
1179+
testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce_HandleNewDataState_OthersNoData {
1180+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultNewData
1181+
anotherObserverResult:UIBackgroundFetchResultNoData
1182+
swizzledResult:UIBackgroundFetchResultNoData
1183+
expecredResult:UIBackgroundFetchResultNewData];
1184+
}
1185+
1186+
- (void)
1187+
testApplicationDidReceiveRemoteNotificationWithCompletionCompletionIsCalledOnce_HandleNewDataState_OthersNoDataFailed {
1188+
[self verifyCompletionCalledForObserverResult:UIBackgroundFetchResultNewData
1189+
anotherObserverResult:UIBackgroundFetchResultNoData
1190+
swizzledResult:UIBackgroundFetchResultFailed
1191+
expecredResult:UIBackgroundFetchResultNewData];
10911192
}
10921193

10931194
- (void)testApplicationDidReceiveRemoteNotificationWithCompletionImplementationIsNotAdded {

ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public let shared = Manifest(
2424
version: "7.1.0",
2525
pods: [
2626
Pod("GoogleUtilities", isFirebase: false, podVersion: "7.1.0", releasing: true),
27-
Pod("GoogleDataTransport", isFirebase: false, podVersion: "8.0.0", releasing: false),
27+
Pod("GoogleDataTransport", isFirebase: false, podVersion: "8.0.1", releasing: true),
2828

2929
Pod("FirebaseCoreDiagnostics"),
3030
Pod("FirebaseCore"),

0 commit comments

Comments
 (0)