Skip to content

Commit 666a86a

Browse files
Fix an issue that notification open is not logged when app is closed (#8129)
1 parent 38b4592 commit 666a86a

File tree

7 files changed

+85
-14
lines changed

7 files changed

+85
-14
lines changed

FirebaseMessaging/Apps/AdvancedSample/Podfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ end
1313

1414
target 'AdvancedSample' do
1515
platform :ios, '13.0'
16+
pod 'FirebaseAnalytics'
1617
shared_pods
1718
end
1819

@@ -23,6 +24,7 @@ end
2324

2425
target 'AppClips' do
2526
platform :ios, '13.0'
27+
pod 'FirebaseAnalytics'
2628
shared_pods
2729
end
2830

FirebaseMessaging/Apps/Sample/Podfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ target 'Sample' do
1111
pod 'FirebaseMessaging', :path => '../../../'
1212
pod 'FirebaseCoreDiagnostics', :path => '../../../'
1313
pod 'FirebaseInstallations', :path => '../../../'
14+
pod 'FirebaseAnalytics'
1415

1516
end

FirebaseMessaging/Apps/Sample/Sample.xcodeproj/xcshareddata/xcschemes/Sample.xcscheme

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
argument = "-FIRDebugEnabled"
5656
isEnabled = "YES">
5757
</CommandLineArgument>
58+
<CommandLineArgument
59+
argument = "-FIRAnalyticsDebugEnabled "
60+
isEnabled = "YES">
61+
</CommandLineArgument>
5862
</CommandLineArguments>
5963
</LaunchAction>
6064
<ProfileAction

FirebaseMessaging/Apps/Shared/AppDelegate.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414

1515
import UIKit
1616
import FirebaseCore
17+
import FirebaseAnalytics
1718

1819
@UIApplicationMain
1920
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
2021
func application(_ application: UIApplication,
2122
didFinishLaunchingWithOptions launchOptions: [UIApplication
2223
.LaunchOptionsKey: Any]?) -> Bool {
2324
FirebaseApp.configure()
25+
FirebaseAnalytics.Analytics.logEvent("test", parameters: nil)
2426

2527
let center = UNUserNotificationCenter.current()
2628
center.delegate = self
@@ -42,14 +44,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
4244
completionHandler([.alert, .sound])
4345
}
4446

45-
// MARK: UISceneSession Lifecycle
46-
47-
func application(_ application: UIApplication,
48-
configurationForConnecting connectingSceneSession: UISceneSession,
49-
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
50-
// Called when a new scene session is being created.
51-
// Use this method to select a configuration to create the new scene with.
52-
return UISceneConfiguration(name: "Default Configuration",
53-
sessionRole: connectingSceneSession.role)
47+
func userNotificationCenter(_ center: UNUserNotificationCenter,
48+
didReceive response: UNNotificationResponse,
49+
withCompletionHandler completionHandler: @escaping () -> Void) {
50+
completionHandler()
5451
}
5552
}

FirebaseMessaging/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# 2021-05 -- v8.1.0
2+
- [fixed] Fixed an issue that notification open is not logged to Analytics correctly when app is completely shut off. (#7707, #8128).
3+
14
# 2021-04 -- v8.0.0
25
- [changed] Remove the Instance ID dependency from Firebase Cloud Messaging. This is a breaking change for FCM users who use the deprecated Instance ID API to manage registration tokens. Users should migrate to FCM's token APIs by following the migration guide: https://firebase.google.com/docs/projects/manage-installations#fid-iid. (#7836)
36

FirebaseMessaging/Sources/FIRMessagingAnalytics.m

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ + (void)logUserPropertyForConversionTracking:(NSDictionary *)notification
189189
+ (void)logMessage:(NSDictionary *)notification
190190
toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics {
191191
// iOS only because Analytics doesn't support other platforms.
192+
192193
#if TARGET_OS_IOS
193194
if (![self canLogNotification:notification]) {
194195
return;
@@ -201,9 +202,12 @@ + (void)logMessage:(NSDictionary *)notification
201202
UIApplicationState applicationState = application.applicationState;
202203
switch (applicationState) {
203204
case UIApplicationStateInactive:
204-
// App was either in background(suspended) or inactive and user tapped on a display
205-
// notification.
206-
[self logOpenNotification:notification toAnalytics:analytics];
205+
// App was in background and in transition to open when user tapped
206+
// on a display notification.
207+
// Needs to check notification is displayed.
208+
if ([[self class] isDisplayNotification:notification]) {
209+
[self logOpenNotification:notification toAnalytics:analytics];
210+
}
207211
break;
208212

209213
case UIApplicationStateActive:
@@ -212,11 +216,34 @@ + (void)logMessage:(NSDictionary *)notification
212216
break;
213217

214218
default:
215-
// Only a silent notification (i.e. 'content-available' is true) can be received while the app
216-
// is in the background. These messages aren't loggable anyway.
219+
// App was either in background state or in transition from closed
220+
// to open.
221+
// Needs to check notification is displayed.
222+
if ([[self class] isDisplayNotification:notification]) {
223+
[self logOpenNotification:notification toAnalytics:analytics];
224+
}
217225
break;
218226
}
219227
#endif
220228
}
221229

230+
+ (BOOL)isDisplayNotification:(NSDictionary *)notification {
231+
NSDictionary *aps = notification[kApsKey];
232+
if (!aps || ![aps isKindOfClass:[NSDictionary class]]) {
233+
return NO;
234+
}
235+
NSDictionary *alert = aps[kApsAlertKey];
236+
if (!alert) {
237+
return NO;
238+
}
239+
if ([alert isKindOfClass:[NSDictionary class]]) {
240+
return alert.allKeys.count > 0;
241+
}
242+
// alert can be string sometimes (if only body is specified)
243+
if ([alert isKindOfClass:[NSString class]]) {
244+
return YES;
245+
}
246+
return NO;
247+
}
248+
222249
@end

FirebaseMessaging/Tests/UnitTests/FIRMessagingAnalyticsTest.m

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ + (void)logEvent:(NSString *)event
140140
withNotification:(NSDictionary *)notification
141141
toAnalytics:(id<FIRAnalyticsInterop> _Nullable)analytics;
142142
;
143+
+ (BOOL)isDisplayNotification:(NSDictionary *)notification;
143144

144145
@end
145146

@@ -447,6 +448,42 @@ - (void)testLogOpenNotification {
447448
toAnalytics:nil]);
448449
}
449450

451+
- (void)testDisplayNotification {
452+
NSDictionary *notification = @{
453+
@"google.c.a.e" : @"1",
454+
};
455+
XCTAssertFalse([FIRMessagingAnalytics isDisplayNotification:notification]);
456+
457+
notification = @{
458+
@"aps" : @{@"alert" : @"to check the reporting format"},
459+
};
460+
XCTAssertTrue([FIRMessagingAnalytics isDisplayNotification:notification]);
461+
462+
notification = @{
463+
@"google.c.a.e" : @"1",
464+
@"aps" : @{@"alert" : @{@"title" : @"Hello World"}},
465+
};
466+
XCTAssertTrue([FIRMessagingAnalytics isDisplayNotification:notification]);
467+
468+
notification = @{
469+
@"google.c.a.e" : @"1",
470+
@"aps" : @{@"alert" : @{@"body" : @"This is the body of notification."}},
471+
};
472+
XCTAssertTrue([FIRMessagingAnalytics isDisplayNotification:notification]);
473+
474+
notification = @{
475+
@"google.c.a.e" : @"1",
476+
@"aps" :
477+
@{@"alert" : @{@"title" : @"Hello World", @"body" : @"This is the body of notification."}},
478+
};
479+
XCTAssertTrue([FIRMessagingAnalytics isDisplayNotification:notification]);
480+
481+
notification = @{
482+
@"google.c.a.e" : @"1",
483+
@"aps" : @{@"alert" : @{@"subtitle" : @"Hello World"}},
484+
};
485+
XCTAssertTrue([FIRMessagingAnalytics isDisplayNotification:notification]);
486+
}
450487
@end
451488

452489
#endif

0 commit comments

Comments
 (0)