Skip to content

Commit 13aaf03

Browse files
exaby73Salakar
andauthored
feat(firebase_analytics): support getSessionId for android and apple platforms (#11478)
Co-authored-by: Salakar <[email protected]>
1 parent 0cedfc8 commit 13aaf03

File tree

9 files changed

+106
-0
lines changed

9 files changed

+106
-0
lines changed

packages/firebase_analytics/firebase_analytics/android/src/main/java/io/flutter/plugins/firebase/analytics/FlutterFirebaseAnalyticsPlugin.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
136136
case "Analytics#getAppInstanceId":
137137
methodCallTask = handleGetAppInstanceId();
138138
break;
139+
case "Analytics#getSessionId":
140+
methodCallTask = handleGetSessionId();
141+
break;
139142
default:
140143
result.notImplemented();
141144
return;
@@ -154,6 +157,21 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
154157
});
155158
}
156159

160+
private Task<Long> handleGetSessionId() {
161+
TaskCompletionSource<Long> taskCompletionSource = new TaskCompletionSource<>();
162+
163+
cachedThreadPool.execute(
164+
() -> {
165+
try {
166+
taskCompletionSource.setResult(Tasks.await(analytics.getSessionId()));
167+
} catch (Exception e) {
168+
taskCompletionSource.setException(e);
169+
}
170+
});
171+
172+
return taskCompletionSource.getTask();
173+
}
174+
157175
private Task<Void> handleLogEvent(final Map<String, Object> arguments) {
158176
TaskCompletionSource<Void> taskCompletionSource = new TaskCompletionSource<>();
159177

packages/firebase_analytics/firebase_analytics/ios/Classes/FLTFirebaseAnalyticsPlugin.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,25 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
7272
[self setDefaultEventParameters:call.arguments withMethodCallResult:methodCallResult];
7373
} else if ([@"Analytics#getAppInstanceId" isEqualToString:call.method]) {
7474
[self getAppInstanceIdWithMethodCallResult:methodCallResult];
75+
} else if ([@"Analytics#getSessionId" isEqualToString:call.method]) {
76+
[self getSessionIdWithMethodCallResult:methodCallResult];
7577
} else {
7678
result(FlutterMethodNotImplemented);
7779
}
7880
}
7981

8082
#pragma mark - Firebase Analytics API
8183

84+
- (void)getSessionIdWithMethodCallResult:(FLTFirebaseMethodCallResult *)result {
85+
[FIRAnalytics sessionIDWithCompletion:^(int64_t sessionID, NSError *_Nullable error) {
86+
if (error != nil) {
87+
result.error(nil, nil, nil, error);
88+
} else {
89+
result.success([NSNumber numberWithLongLong:sessionID]);
90+
}
91+
}];
92+
}
93+
8294
- (void)logEvent:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
8395
NSString *eventName = arguments[kFLTFirebaseAnalyticsEventName];
8496
id parameterMap = arguments[kFLTFirebaseAnalyticsParameters];

packages/firebase_analytics/firebase_analytics/lib/src/firebase_analytics.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ class FirebaseAnalytics extends FirebasePluginPlatform {
7575
return _delegate.getAppInstanceId();
7676
}
7777

78+
/// Retrieves the session id from the client. Returns null if
79+
/// analyticsStorageConsentGranted is false or session is expired.
80+
Future<int?> getSessionId() {
81+
return _delegate.getSessionId();
82+
}
83+
7884
/// Logs a custom Flutter Analytics event with the given [name] and event
7985
/// [parameters].
8086
///

packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform {
4444
return Future.value(true);
4545
}
4646

47+
@override
48+
Future<int?> getSessionId() {
49+
try {
50+
return channel.invokeMethod<int>('Analytics#getSessionId');
51+
} catch (e, s) {
52+
convertPlatformException(e, s);
53+
}
54+
}
55+
4756
@override
4857
Future<void> logEvent({
4958
required String name,

packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/platform_interface/platform_interface_firebase_analytics.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface {
7474
throw UnimplementedError('getAppInstanceId() is not implemented');
7575
}
7676

77+
Future<int?> getSessionId() {
78+
throw UnimplementedError('getSessionId() is not implemented');
79+
}
80+
7781
/// Logs a custom Flutter Analytics event with the given [name] and event
7882
/// [parameters].
7983
///

packages/firebase_analytics/firebase_analytics_platform_interface/test/method_channel_tests/method_channel_firebase_analytics_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ void main() {
2424
switch (call.method) {
2525
case 'Analytics#getAppInstanceId':
2626
return 'ABCD1234';
27+
case 'Analytics#getSessionId':
28+
return 0;
2729

2830
default:
2931
return true;
@@ -133,6 +135,19 @@ void main() {
133135
);
134136
});
135137

138+
test('getSessionId', () async {
139+
await analytics.getSessionId();
140+
expect(
141+
methodCallLogger,
142+
<Matcher>[
143+
isMethodCall(
144+
'Analytics#getSessionId',
145+
arguments: null,
146+
),
147+
],
148+
);
149+
});
150+
136151
test('logEvent', () async {
137152
await analytics.logEvent(
138153
name: 'test-event',

packages/firebase_analytics/firebase_analytics_platform_interface/test/platform_interface_tests/platform_interface_analytics_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,19 @@ void main() {
211211
),
212212
);
213213
});
214+
215+
test('throws if .getSessionId() not implemented', () async {
216+
await expectLater(
217+
() => firebaseAnalyticsPlatform.getSessionId(),
218+
throwsA(
219+
isA<UnimplementedError>().having(
220+
(e) => e.message,
221+
'message',
222+
'getSessionId() is not implemented',
223+
),
224+
),
225+
);
226+
});
214227
});
215228
}
216229

packages/firebase_analytics/firebase_analytics_web/lib/firebase_analytics_web.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform {
4343
return analytics_interop.Analytics.isSupported();
4444
}
4545

46+
@override
47+
Future<int?> getSessionId() {
48+
// TODO: change UnimplementedError to UnsupportedError
49+
throw UnimplementedError('getSessionId() is not supported on Web.');
50+
}
51+
4652
@override
4753
Future<void> logEvent({
4854
required String name,

tests/integration_test/firebase_analytics/firebase_analytics_e2e_test.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,29 @@ void main() {
1919
);
2020
});
2121

22+
// getSessionId has to be first, else Android returns null
23+
test(
24+
'getSessionId',
25+
() async {
26+
if (kIsWeb) {
27+
await expectLater(
28+
FirebaseAnalytics.instance.getSessionId(),
29+
throwsA(isA<UnimplementedError>()),
30+
);
31+
} else {
32+
await expectLater(
33+
FirebaseAnalytics.instance.setConsent(
34+
analyticsStorageConsentGranted: true,
35+
),
36+
completes,
37+
);
38+
39+
final result = await FirebaseAnalytics.instance.getSessionId();
40+
expect(result, isA<int>());
41+
}
42+
},
43+
);
44+
2245
test('isSupported', () async {
2346
final result = await FirebaseAnalytics.instance.isSupported();
2447
expect(result, isA<bool>());

0 commit comments

Comments
 (0)