trySave method
Call this method at the start of app
Implementation
Future<void> trySave({
@Deprecated('use fbRegion')
final String iosRegion = '',
final String fbV1Region = '',
final String fbV2Url = '',
final bool forceFBReferrer = false,
Map<String, Object> Function(Map<String, String> fields)? installParamsExtra,
}) async {
assert(!_isInitialized, 'Duplicate trySave call not needed');
var params = 0;
if (iosRegion.isNotEmpty) params++;
if (fbV1Region.isNotEmpty) params++;
if (fbV2Url.isNotEmpty) params++;
assert(params <= 1, 'Use fbV1Region or fbV2Url parameter only');
final region = fbV1Region.isEmpty ? iosRegion : fbV1Region;
_isInitialized = true;
try {
final prefs = DSPrefs.I.internal;
var referrer = prefs.getString(_referrerKey) ?? '';
try {
if (referrer.isEmpty) {
final res = await Future.wait<String>([
if (Platform.isIOS || forceFBReferrer)
() async {
assert(region.isNotEmpty || fbV2Url.isNotEmpty, 'fbRegion should be assigned (get_referrer cloud function must be deployed)');
try {
final startTime = DateTime.timestamp();
final int respCode;
if (fbV2Url.isEmpty) {
final res = await FirebaseFunctions.instanceFor(region: region).httpsCallable('get_referrer').call<String>();
respCode = 200;
referrer = res.data;
} else {
final res = await http.get(
Uri.parse(fbV2Url),
);
respCode = res.statusCode;
if (respCode == 200) {
referrer = res.body;
}
}
final loadTime = DateTime.timestamp().difference(startTime);
DSMetrica.reportEvent('fb_referrer', attributes: {
'value': referrer,
'resp_code': respCode,
'referrer_load_seconds': loadTime.inSeconds,
'referrer_load_milliseconds': loadTime.inMilliseconds,
});
final p = referrer.indexOf('?');
if (p >= 0) {
referrer = referrer.substring(p + 1);
}
return referrer;
} catch (e, stack) {
Fimber.e('fb_referrer $e', stacktrace: stack);
return 'err_fb';
}
} (),
if (Platform.isAndroid)
() async {
try {
final startTime = DateTime.timestamp();
final ref = await DSInternal.platform.invokeMethod('fetchInstallReferrer') as String;
final loadTime = DateTime.timestamp().difference(startTime);
DSMetrica.reportEvent('android_referrer', attributes: {
'value': referrer,
'referrer_load_seconds': loadTime.inSeconds,
'referrer_load_milliseconds': loadTime.inMilliseconds,
});
return ref;
} catch (e, stack) {
Fimber.e('android_referrer $e', stacktrace: stack);
return 'err_android';
}
} (),
]);
referrer = res.join('&');
await prefs.setString(_referrerKey, referrer);
}
Fimber.i('ds_referrer=$referrer');
if (!DSConstants.I.isInternalVersion) {
if (isKnownReferrer()) {
DSRemoteConfig.I.setPostfix('_r');
} else {
DSRemoteConfig.I.setPostfix('_e');
}
}
// Send installs_full_referrer once. Only for Android platform
if (prefs.getBool(_isSentKey) == true || !Platform.isAndroid) return;
if (referrer == '') return;
final data = Uri.splitQueryString(referrer);
final utmSource = data['utm_source'];
if (utmSource == null) return;
final fid = await FirebaseInstallations.instance.getId();
unawaited(FirebaseFirestore.instance.collection('installs_full_referrer').add({
'bundle': DSConstants.I.packageInfo.packageName,
'referrer': referrer,
'referrer_len': referrer.length,
'utm_source': utmSource,
'firebase_id': fid,
'timestamp': FieldValue.serverTimestamp(),
}).then((value) {
prefs.setBool(_isSentKey, true);
}).timeout(const Duration(minutes: 1)));
{
final String utmSource = data['utm_source'] ?? '';
final isValidFb = utmSource.contains('apps.facebook.com') || utmSource.contains('apps.instagram.com');
DSMetrica.reportEvent('install_params', fbSend: true, fbAttributes: {
'gclid': data['gclid'] ?? '',
'ad_imp': data['adimp'] ?? '',
'utm_source': utmSource,
'utm_content': data['utm_content'] ?? '',
'is_valid_fb_flow': isValidFb.toString(),
'campaign': data['utm_campaign'] ?? 'unknown',
'adjust_external_click_id': adjustExternalClickId,
if (installParamsExtra != null)
...installParamsExtra(data)
});
}
} catch (e, stack) {
Fimber.e('$e: (referrer: $referrer)', stacktrace: stack);
}
} finally {
final data = getReferrerFields();
for (final callback in _changedCallbacks) {
callback(data);
}
}
}