reconcilePendingFirstOpen static method
Implementation
static Future<bool> reconcilePendingFirstOpen(
int initTimestamp, {
required Future<bool?> Function(String eventName, int tsMillis)
lookupEventPresence,
Future<void> Function(Event event)? persistEvent,
required bool allowReplayWithoutSignal,
}) async {
final isSent = Prefs.getBool(_isSentKey) ?? false;
if (isSent) return true;
final isPending = Prefs.getBool(_pendingDurableKey) ?? false;
if (!isPending) return true;
final hasLocalStoreProvenance = Prefs.containsKey(_pendingLocallyStoredKey);
final locallyStored = Prefs.getBool(_pendingLocallyStoredKey) ?? false;
final isLegacyAmbiguous = _isLegacyAmbiguousPendingState(
hasLocalStoreProvenance: hasLocalStoreProvenance,
);
final firstOpenTime = Prefs.getInt('first_open_time') ?? -1;
if (firstOpenTime == -1) return false;
final existing = await lookupEventPresence('first_open', firstOpenTime);
if (existing == true) {
if (isLegacyAmbiguous || !locallyStored) {
await _markFirstOpenLocallyStored();
}
return true;
}
if (existing == null) {
return false;
}
if (!allowReplayWithoutSignal && hasLocalStoreProvenance && locallyStored) {
try {
await markFirstOpenDelivered();
return true;
} catch (e, st) {
dbLogger.warning(
'FirstOpenTracker: failed to repair pending first_open delivery marker without a storage recovery signal',
e,
st,
);
return false;
}
}
if (!allowReplayWithoutSignal && isLegacyAmbiguous) {
await _markFirstOpenLegacyAmbiguousUnresolved();
dbLogger.warning(
'FirstOpenTracker: leaving legacy ambiguous pending first_open unresolved because the storage row is missing and no recovery replay signal is armed',
);
return false;
}
if (isLegacyAmbiguous) {
await _markFirstOpenNotLocallyStored();
}
final now = DateTime.now().millisecondsSinceEpoch;
if (now - _lastReplayAttemptTs < _replayCooldownMs) {
return false;
}
_lastReplayAttemptTs = now;
final diff = Prefs.getInt(_pendingInstallDiffKey) ??
(initTimestamp - firstOpenTime);
await _recordFirstOpenEvent(
firstOpenTime,
diff,
recordEvent: persistEvent ?? onRecordEvent,
);
await _confirmPendingFirstOpenStored(
firstOpenTime,
lookupEventPresence: lookupEventPresence,
);
return await lookupEventPresence('first_open', firstOpenTime) == true;
}