Skip to content

Commit

Permalink
feat: 5095 - matomo anonymous visitor id now starts with a persistent…
Browse files Browse the repository at this point in the history
… letter (openfoodfacts#5107)

Impacted files:
* `analytics_helper.dart`: new getter `_anonymousVisitorId`; refactoring
* `main.dart`: minor refactoring
* `user_preferences.dart`: new method `getUniqueRandom()` that is used to compute and store the first letter of the anonymous visitor ID.
  • Loading branch information
monsieurtanuki authored Mar 8, 2024
1 parent 98de444 commit f1d0992
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class UserPreferences extends ChangeNotifier {
static const String _TAG_CRASH_REPORTS = 'crash_reports';
static const String _TAG_EXCLUDED_ATTRIBUTE_IDS = 'excluded_attributes';
static const String _TAG_USER_GROUP = '_user_group';
static const String _TAG_UNIQUE_RANDOM = '_unique_random';

/// Camera preferences
Expand Down Expand Up @@ -171,6 +172,18 @@ class UserPreferences extends ChangeNotifier {
/// A random int between 0 and 10 (a naive implementation to allow A/B testing)
int get userGroup => _sharedPreferences.getInt(_TAG_USER_GROUP)!;

/// Returns a huge random value that will be computed just once.
Future<int> getUniqueRandom() async {
const String tag = _TAG_UNIQUE_RANDOM;
int? result = _sharedPreferences.getInt(tag);
if (result != null) {
return result;
}
result = Random().nextInt(1 << 32);
await _sharedPreferences.setInt(tag, result);
return result;
}

Future<void> setCrashReports(final bool state) async {
await _sharedPreferences.setBool(_TAG_CRASH_REPORTS, state);
onCrashReportingChanged.value = state;
Expand Down
23 changes: 17 additions & 6 deletions packages/smooth_app/lib/helpers/analytics_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ class AnalyticsHelper {

static String latestSearch = '';

static void linkPreferences(UserPreferences userPreferences) {
static late int _uniqueRandom;

static Future<void> linkPreferences(UserPreferences userPreferences) async {
// Init the value
_setAnalyticsReports(userPreferences.onAnalyticsChanged.value);
_setCrashReports(userPreferences.onCrashReportingChanged.value);
Expand All @@ -206,6 +208,8 @@ class AnalyticsHelper {
userPreferences.onCrashReportingChanged.addListener(() {
_setCrashReports(userPreferences.onCrashReportingChanged.value);
});

_uniqueRandom = await userPreferences.getUniqueRandom();
}

static Future<void> initSentry({
Expand Down Expand Up @@ -253,7 +257,7 @@ class AnalyticsHelper {
}

if (MatomoTracker.instance.initialized) {
MatomoTracker.instance.setVisitorUserId(_uuid);
MatomoTracker.instance.setVisitorUserId(_visitorId);
}
}

Expand Down Expand Up @@ -281,30 +285,37 @@ class AnalyticsHelper {
await MatomoTracker.instance.initialize(
url: 'https://analytics.openfoodfacts.org/matomo.php',
siteId: 2,
visitorId: _uuid,
visitorId: _visitorId,
);
} catch (err) {
// With Hot Reload, this may trigger a late field already initialized
}
}

/// A UUID must be at least one 16 characters
static String? get _uuid {
/// A visitor id should have a length of 16 characters.
static String? get _visitorId {
// if user opts out then track anonymously with userId containing zeros
if (kDebugMode) {
return 'smoothie_debug--';
}

switch (_analyticsReporting) {
case _AnalyticsTrackingMode.anonymous:
return '0' * 16;
return _anonymousVisitorId;
case _AnalyticsTrackingMode.disabled:
return '';
case _AnalyticsTrackingMode.enabled:
return OpenFoodAPIConfiguration.uuid;
}
}

/// Returns a unique visitor id that starts with a letter between A and Z.
static String get _anonymousVisitorId => _uniqueLetter + ('0' * 15);

/// Returns a letter between A and Z, depending on [_uniqueRandom].
static String get _uniqueLetter =>
String.fromCharCode('A'.codeUnitAt(0) + _uniqueRandom % 26);

static void trackEvent(
AnalyticsEvent msg, {
int? eventValue,
Expand Down
2 changes: 1 addition & 1 deletion packages/smooth_app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Future<bool> _init1() async {
);
UserManagementProvider().checkUserLoginValidity();

AnalyticsHelper.linkPreferences(_userPreferences);
await AnalyticsHelper.linkPreferences(_userPreferences);

await ProductQuery.initCountry(_userPreferences);
_themeProvider = ThemeProvider(_userPreferences);
Expand Down

0 comments on commit f1d0992

Please sign in to comment.