checkForUpdate method

Future<void> checkForUpdate()

Checks for available updates by comparing current app version with Firestore.

This method:

  1. Fetches current app version using package_info_plus
  2. Detects platform (Android/iOS) automatically
  3. Queries Firestore for available versions
  4. Shows update dialog if exact version match is found
  5. Handles force updates and optional updates
  6. Launches store URL when user chooses to update

Firestore Structure:

Expects a collection named 'AppUpdateManager' with documents for each platform:

  • Document 'Android' for Android platform
  • Document 'Ios' for iOS platform

Each document should contain:

  • androidId and iosId fields (for store URLs)
  • versions array with version objects

Version object structure:

{
  "version": "1.2.0",
  "forceUpdate": false
}

Returns:

Future

Throws:

May throw exceptions for network errors or invalid Firestore data

Implementation

Future<void> checkForUpdate() async {
  debugPrint('AppUpdateManager: Starting update check...');

  // Auto setup if enabled
  if (autoSetup) {
    await _autoSetupFirestore();
  }

  final packageInfo = await PackageInfo.fromPlatform();
  final currentVersion = packageInfo.version;
  debugPrint('AppUpdateManager: Current app version: $currentVersion');

  final platform = Theme.of(context).platform == TargetPlatform.android
      ? 'Android'
      : 'Ios';
  debugPrint('AppUpdateManager: Platform detected: $platform');

  try {
    // Firebase is always initialized since it's required in constructor

    final doc = await firestore
        .collection('AppUpdateManager')
        .doc(platform)
        .get();
    debugPrint('AppUpdateManager: Firestore document exists: ${doc.exists}');

    if (doc.exists) {
      final data = doc.data() as Map<String, dynamic>;

      // App IDs are fetched later when needed for URL generation

      // Check for new simplified structure first
      if (data.containsKey('versions') && data['versions'] is List) {
        final versions = data['versions'] as List<dynamic>;
        debugPrint('AppUpdateManager: Using simplified version structure');
        debugPrint('AppUpdateManager: Versions from Firestore: $versions');

        // Find exact version match
        bool foundExactMatch = false;
        bool shouldShowDialog = false;
        bool isForceUpdate = false;

        for (var versionData in versions) {
          final version = versionData['version'] as String;
          final forceUpdate = versionData['forceUpdate'] as bool? ?? false;

          debugPrint(
            'AppUpdateManager: Checking version: $version (forceUpdate: $forceUpdate)',
          );
          debugPrint(
            'AppUpdateManager: Current app version: $currentVersion',
          );

          // Check for exact match first (version + build number)
          if (version == currentVersion) {
            foundExactMatch = true;
            shouldShowDialog = true;
            isForceUpdate = forceUpdate;
            debugPrint(
              'AppUpdateManager: Exact version match found, showing dialog',
            );
            break;
          }

          // If no exact match, check if Firestore version is without build number
          // and current version has build number, then compare version parts
          if (!version.contains('+') && currentVersion.contains('+')) {
            final currentVersionWithoutBuild = currentVersion.split('+')[0];
            if (version == currentVersionWithoutBuild) {
              foundExactMatch = true;
              shouldShowDialog = true;
              isForceUpdate = forceUpdate;
              debugPrint(
                'AppUpdateManager: Version match found (Firestore without build, app with build), showing dialog',
              );
              break;
            }
          }

          // If Firestore version has build number but app version doesn't, compare version parts
          if (version.contains('+') && !currentVersion.contains('+')) {
            final firestoreVersionWithoutBuild = version.split('+')[0];
            if (firestoreVersionWithoutBuild == currentVersion) {
              foundExactMatch = true;
              shouldShowDialog = true;
              isForceUpdate = forceUpdate;
              debugPrint(
                'AppUpdateManager: Version match found (Firestore with build, app without build), showing dialog',
              );
              break;
            }
          }
        }

        if (shouldShowDialog) {
          _showUpdateDialog(isForceUpdate: isForceUpdate);
          return;
        }

        if (!foundExactMatch) {
          debugPrint(
            'AppUpdateManager: No exact version match found, no update needed',
          );
        }
        return;
      }

      // Fallback to original structure
      final versions = data['versions'] as List<dynamic>;

      debugPrint('AppUpdateManager: Using original version structure');
      debugPrint('AppUpdateManager: Versions from Firestore: $versions');

      // Check for newer versions
      for (var versionData in versions) {
        final firestoreVersion = versionData['version'] as String;

        // Check for exact match first
        if (firestoreVersion == currentVersion) {
          debugPrint(
            'AppUpdateManager: Exact version match found, showing update dialog',
          );
          _showUpdateDialog(isForceUpdate: versionData['forceUpdate']);
          break;
        }

        // If no exact match, check if Firestore version is without build number
        // and current version has build number, then compare version parts
        if (!firestoreVersion.contains('+') && currentVersion.contains('+')) {
          final currentVersionWithoutBuild = currentVersion.split('+')[0];
          if (firestoreVersion == currentVersionWithoutBuild) {
            debugPrint(
              'AppUpdateManager: Version match found (Firestore without build, app with build), showing dialog',
            );
            _showUpdateDialog(isForceUpdate: versionData['forceUpdate']);
            break;
          }
        }

        // If Firestore version has build number but app version doesn't, compare version parts
        if (firestoreVersion.contains('+') && !currentVersion.contains('+')) {
          final firestoreVersionWithoutBuild = firestoreVersion.split('+')[0];
          if (firestoreVersionWithoutBuild == currentVersion) {
            debugPrint(
              'AppUpdateManager: Version match found (Firestore with build, app without build), showing dialog',
            );
            _showUpdateDialog(isForceUpdate: versionData['forceUpdate']);
            break;
          }
        }
      }
    } else {
      debugPrint(
        'AppUpdateManager: No Firestore document found for platform: $platform',
      );
    }
  } catch (e) {
    debugPrint('AppUpdateManager: Error during update check: $e');
  }
}