Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import androidx.annotation.NonNull;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.TaskCompletionSource;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.FirebaseApp;
import com.google.firebase.analytics.FirebaseAnalytics;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
Expand Down Expand Up @@ -130,6 +131,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
case "Analytics#setDefaultEventParameters":
methodCallTask = setDefaultEventParameters(call.arguments());
break;
case "Analytics#getAppInstanceId":
methodCallTask = handleGetAppInstanceId();
break;
default:
result.notImplemented();
return;
Expand Down Expand Up @@ -313,6 +317,21 @@ private Task<Void> setDefaultEventParameters(final Map<String, Object> arguments
return taskCompletionSource.getTask();
}

private Task<String> handleGetAppInstanceId() {
TaskCompletionSource<String> taskCompletionSource = new TaskCompletionSource<>();

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

return taskCompletionSource.getTask();
}

@Override
public Task<Map<String, Object>> getPluginConstantsForFirebaseApp(FirebaseApp firebaseApp) {
TaskCompletionSource<Map<String, Object>> taskCompletionSource = new TaskCompletionSource<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'

android {
compileSdkVersion 29
compileSdkVersion 31

lintOptions {
disable 'InvalidPackage'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ class _MyHomePageState extends State<MyHomePage> {
setMessage('setUserProperty succeeded');
}

Future<void> _testAppInstanceId() async {
String? id = await widget.analytics.appInstanceId;
if (id != null) {
setMessage('appInstanceId succeeded: $id');
} else {
setMessage('appInstanceId failed, consent declined');
}
}

Future<void> _testResetAnalyticsData() async {
await widget.analytics.resetAnalyticsData();
setMessage('resetAnalyticsData succeeded');
}

AnalyticsEventItem itemCreator() {
return AnalyticsEventItem(
affiliation: 'affil',
Expand Down Expand Up @@ -303,6 +317,14 @@ class _MyHomePageState extends State<MyHomePage> {
onPressed: _testSetUserProperty,
child: const Text('Test setUserProperty'),
),
MaterialButton(
onPressed: _testAppInstanceId,
child: const Text('Test appInstanceId'),
),
MaterialButton(
onPressed: _testResetAnalyticsData,
child: const Text('Test resetAnalyticsData'),
),
Text(
_message,
style: const TextStyle(color: Color.fromARGB(255, 0, 155, 0)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,29 @@ void testsMain() {
}
},
);

test('appInstanceId', () async {
if (kIsWeb) {
await expectLater(
FirebaseAnalytics.instance.appInstanceId,
throwsA(isA<UnimplementedError>()),
);
} else {
final result = await FirebaseAnalytics.instance.appInstanceId;
expect(result, isNull);

await expectLater(
FirebaseAnalytics.instance.setConsent(
analyticsStorageConsentGranted: true,
adStorageConsentGranted: false,
),
completes,
);

final result2 = await FirebaseAnalytics.instance.appInstanceId;
expect(result2, isA<String>());
}
});
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
[self setConsent:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Analytics#setDefaultEventParameters" isEqualToString:call.method]) {
[self setDefaultEventParameters:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Analytics#getAppInstanceId" isEqualToString:call.method]) {
[self getAppInstanceIdWithMethodCallResult:methodCallResult];
} else {
result(FlutterMethodNotImplemented);
}
Expand Down Expand Up @@ -142,6 +144,11 @@ - (void)setDefaultEventParameters:(id)arguments
result.success(nil);
}

- (void)getAppInstanceIdWithMethodCallResult:(FLTFirebaseMethodCallResult *)result {
NSString *appInstanceID = [FIRAnalytics appInstanceID];
result.success(appInstanceID);
}

#pragma mark - FLTFirebasePlugin

- (void)didReinitializeFirebaseCore:(void (^_Nonnull)(void))completion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ class FirebaseAnalytics extends FirebasePluginPlatform {
return _delegate.isSupported();
}

/// Retrieves the app instance id from the service, or null if consent has
/// been denied.
Future<String?> get appInstanceId {
return _delegate.getAppInstanceId();
}

/// Logs a custom Flutter Analytics event with the given [name] and event [parameters].
Future<void> logEvent({
required String name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,19 @@ void main() {
],
);
});

test('appInstanceId', () async {
var _ = await analytics!.appInstanceId;
expect(
methodCallLog,
<Matcher>[
isMethodCall(
'Analytics#getAppInstanceId',
arguments: null,
)
],
);
});
});
});
}
3 changes: 3 additions & 0 deletions packages/firebase_analytics/firebase_analytics/test/mock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ void setupFirebaseAnalyticsMocks([Callback? customHandlers]) {
.setMockMethodCallHandler((MethodCall methodCall) async {
methodCallLog.add(methodCall);
switch (methodCall.method) {
case 'Analytics#getAppInstanceId':
return 'ABCD1234';

default:
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform {
}
}

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

@override
Future<void> setSessionTimeoutDuration(Duration timeout) async {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ abstract class FirebaseAnalyticsPlatform extends PlatformInterface {
throw UnimplementedError('isSupported() is not implemented');
}

/// Retrieves the app instance id from the service.
Future<String?> getAppInstanceId() {
throw UnimplementedError('getAppInstanceId() is not implemented');
}

/// Logs the given event [name] with the given [parameters].
Future<void> logEvent({
required String name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ void main() {
methodCallLogger.add(call);

switch (call.method) {
case 'Analytics#getAppInstanceId':
return 'ABCD1234';

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

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

test('logEvent', () async {
await analytics.logEvent(
name: 'test-event',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ void setupFirebaseAnalyticsMocks([Callback? customHandlers]) {
.setMockMethodCallHandler((MethodCall methodCall) async {
methodCallLog.add(methodCall);
switch (methodCall.method) {
case 'Analytics#getAppInstanceId':
return 'ABCD1234';

default:
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,19 @@ void main() {
),
);
});

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,11 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform {
'setDefaultEventParameters() is not supported on web',
);
}

@override
Future<String?> getAppInstanceId() async {
throw UnimplementedError(
'getAppInstanceId() is not supported on web',
);
}
}
23 changes: 23 additions & 0 deletions tests/test_driver/firebase_analytics/firebase_analytics_e2e.dart
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,28 @@ void setupTests() {
}
},
);

test('appInstanceId', () async {
if (kIsWeb) {
await expectLater(
FirebaseAnalytics.instance.appInstanceId,
throwsA(isA<UnimplementedError>()),
);
} else {
final result = await FirebaseAnalytics.instance.appInstanceId;
expect(result, isNull);

await expectLater(
FirebaseAnalytics.instance.setConsent(
analyticsStorageConsentGranted: true,
adStorageConsentGranted: false,
),
completes,
);

final result2 = await FirebaseAnalytics.instance.appInstanceId;
expect(result2, isA<String>());
}
});
});
}