Skip to content

Commit

Permalink
feat(firebase_analytics): support getSessionId for android and appl…
Browse files Browse the repository at this point in the history
…e platforms (#11478)

Co-authored-by: Salakar <mike@invertase.io>
  • Loading branch information
exaby73 and Salakar committed Sep 12, 2023
1 parent 0cedfc8 commit 13aaf03
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 0 deletions.
Expand Up @@ -136,6 +136,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
case "Analytics#getAppInstanceId":
methodCallTask = handleGetAppInstanceId();
break;
case "Analytics#getSessionId":
methodCallTask = handleGetSessionId();
break;
default:
result.notImplemented();
return;
Expand All @@ -154,6 +157,21 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
});
}

private Task<Long> handleGetSessionId() {
TaskCompletionSource<Long> taskCompletionSource = new TaskCompletionSource<>();

cachedThreadPool.execute(
() -> {
try {
taskCompletionSource.setResult(Tasks.await(analytics.getSessionId()));
} catch (Exception e) {
taskCompletionSource.setException(e);
}
});

return taskCompletionSource.getTask();
}

private Task<Void> handleLogEvent(final Map<String, Object> arguments) {
TaskCompletionSource<Void> taskCompletionSource = new TaskCompletionSource<>();

Expand Down
Expand Up @@ -72,13 +72,25 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
[self setDefaultEventParameters:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Analytics#getAppInstanceId" isEqualToString:call.method]) {
[self getAppInstanceIdWithMethodCallResult:methodCallResult];
} else if ([@"Analytics#getSessionId" isEqualToString:call.method]) {
[self getSessionIdWithMethodCallResult:methodCallResult];
} else {
result(FlutterMethodNotImplemented);
}
}

#pragma mark - Firebase Analytics API

- (void)getSessionIdWithMethodCallResult:(FLTFirebaseMethodCallResult *)result {
[FIRAnalytics sessionIDWithCompletion:^(int64_t sessionID, NSError *_Nullable error) {
if (error != nil) {
result.error(nil, nil, nil, error);
} else {
result.success([NSNumber numberWithLongLong:sessionID]);
}
}];
}

- (void)logEvent:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
NSString *eventName = arguments[kFLTFirebaseAnalyticsEventName];
id parameterMap = arguments[kFLTFirebaseAnalyticsParameters];
Expand Down
Expand Up @@ -75,6 +75,12 @@ class FirebaseAnalytics extends FirebasePluginPlatform {
return _delegate.getAppInstanceId();
}

/// Retrieves the session id from the client. Returns null if
/// analyticsStorageConsentGranted is false or session is expired.
Future<int?> getSessionId() {
return _delegate.getSessionId();
}

/// Logs a custom Flutter Analytics event with the given [name] and event
/// [parameters].
///
Expand Down
Expand Up @@ -44,6 +44,15 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform {
return Future.value(true);
}

@override
Future<int?> getSessionId() {
try {
return channel.invokeMethod<int>('Analytics#getSessionId');
} catch (e, s) {
convertPlatformException(e, s);
}
}

@override
Future<void> logEvent({
required String name,
Expand Down
Expand Up @@ -74,6 +74,10 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface {
throw UnimplementedError('getAppInstanceId() is not implemented');
}

Future<int?> getSessionId() {
throw UnimplementedError('getSessionId() is not implemented');
}

/// Logs a custom Flutter Analytics event with the given [name] and event
/// [parameters].
///
Expand Down
Expand Up @@ -24,6 +24,8 @@ void main() {
switch (call.method) {
case 'Analytics#getAppInstanceId':
return 'ABCD1234';
case 'Analytics#getSessionId':
return 0;

default:
return true;
Expand Down Expand Up @@ -133,6 +135,19 @@ void main() {
);
});

test('getSessionId', () async {
await analytics.getSessionId();
expect(
methodCallLogger,
<Matcher>[
isMethodCall(
'Analytics#getSessionId',
arguments: null,
),
],
);
});

test('logEvent', () async {
await analytics.logEvent(
name: 'test-event',
Expand Down
Expand Up @@ -211,6 +211,19 @@ void main() {
),
);
});

test('throws if .getSessionId() not implemented', () async {
await expectLater(
() => firebaseAnalyticsPlatform.getSessionId(),
throwsA(
isA<UnimplementedError>().having(
(e) => e.message,
'message',
'getSessionId() is not implemented',
),
),
);
});
});
}

Expand Down
Expand Up @@ -43,6 +43,12 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform {
return analytics_interop.Analytics.isSupported();
}

@override
Future<int?> getSessionId() {
// TODO: change UnimplementedError to UnsupportedError
throw UnimplementedError('getSessionId() is not supported on Web.');
}

@override
Future<void> logEvent({
required String name,
Expand Down
Expand Up @@ -19,6 +19,29 @@ void main() {
);
});

// getSessionId has to be first, else Android returns null
test(
'getSessionId',
() async {
if (kIsWeb) {
await expectLater(
FirebaseAnalytics.instance.getSessionId(),
throwsA(isA<UnimplementedError>()),
);
} else {
await expectLater(
FirebaseAnalytics.instance.setConsent(
analyticsStorageConsentGranted: true,
),
completes,
);

final result = await FirebaseAnalytics.instance.getSessionId();
expect(result, isA<int>());
}
},
);

test('isSupported', () async {
final result = await FirebaseAnalytics.instance.isSupported();
expect(result, isA<bool>());
Expand Down

0 comments on commit 13aaf03

Please sign in to comment.