From 4813376ae36da1a60583282c1dde863616515f8a Mon Sep 17 00:00:00 2001 From: Frederik St-Onge Date: Mon, 6 Jan 2025 13:42:00 -0500 Subject: [PATCH] Use versions from firebase_core pubspec --- .../src/firebase/firebase_android_writes.dart | 78 +++++++++++++++---- .../src/firebase/firebase_pubspec_model.dart | 19 +++++ 2 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 packages/flutterfire_cli/lib/src/firebase/firebase_pubspec_model.dart diff --git a/packages/flutterfire_cli/lib/src/firebase/firebase_android_writes.dart b/packages/flutterfire_cli/lib/src/firebase/firebase_android_writes.dart index 9fe60a65..452048a3 100644 --- a/packages/flutterfire_cli/lib/src/firebase/firebase_android_writes.dart +++ b/packages/flutterfire_cli/lib/src/firebase/firebase_android_writes.dart @@ -1,11 +1,15 @@ import 'dart:io'; import 'package:cli_util/cli_logging.dart'; +import 'package:collection/collection.dart'; import 'package:path/path.dart' as path; +import 'package:pubspec/pubspec.dart'; +import 'package:yaml/yaml.dart'; import '../common/strings.dart'; import '../common/utils.dart'; import '../flutter_app.dart'; import 'firebase_options.dart'; +import 'firebase_pubspec_model.dart'; // https://regex101.com/r/Lj93lx/1 final _androidBuildGradleRegex = RegExp( @@ -31,22 +35,13 @@ final _androidAppBuildGradleGoogleServicesRegex = RegExp( // Google services JSON. const _googleServicesPluginClass = 'com.google.gms:google-services'; const _googleServicesPluginName = 'com.google.gms.google-services'; -// TODO read from firebase_core pubspec.yaml firebase.google_services_gradle_plugin_version -const _googleServicesPluginVersion = '4.3.15'; -const _googleServicesPlugin = - "classpath '$_googleServicesPluginClass:$_googleServicesPluginVersion'"; // Firebase Crashlytics -const _crashlyticsPluginClassPath = - 'com.google.firebase:firebase-crashlytics-gradle'; -// TODO read from firebase_core pubspec.yaml firebase.crashlytics_gradle_plugin_version -const _crashlyticsPluginClassPathVersion = '2.8.1'; +const _crashlyticsPluginClassPath = 'com.google.firebase:firebase-crashlytics-gradle'; const _crashlyticsPluginClass = 'com.google.firebase.crashlytics'; // Firebase Performance const _performancePluginClassPath = 'com.google.firebase:perf-plugin'; -// TODO read from firebase_core pubspec.yaml firebase.performance_gradle_plugin_version -const _performancePluginClassPathVersion = '1.4.1'; const _performancePluginClass = 'com.google.firebase.firebase-perf'; const _flutterFireConfigCommentStart = '// START: FlutterFire Configuration'; @@ -205,6 +200,8 @@ Future gradleContentUpdates( ), ); + final firebaseCorePubSpec = await getFirebaseCorePubSpec(); + final androidGradleSettingsFileContents = androidGradleSettingsFile.readAsStringSync(); @@ -224,16 +221,19 @@ Future gradleContentUpdates( flutterApp, content, BuildGradleConfiguration.legacy1, + firebaseCorePubSpec.googleServicesGradlePluginVersion, ); content = _applyCrashlyticsPlugin( flutterApp, content, BuildGradleConfiguration.legacy1, + firebaseCorePubSpec.crashlyticsGradlePluginVersion, ); content = _applyPerformancePlugin( flutterApp, content, BuildGradleConfiguration.legacy1, + firebaseCorePubSpec.performanceGradlePluginVersion, ); } @@ -250,16 +250,19 @@ Future gradleContentUpdates( flutterApp, content, BuildGradleConfiguration.legacy2, + firebaseCorePubSpec.googleServicesGradlePluginVersion, ); content = _applyCrashlyticsPlugin( flutterApp, content, BuildGradleConfiguration.legacy2, + firebaseCorePubSpec.crashlyticsGradlePluginVersion, ); content = _applyPerformancePlugin( flutterApp, content, BuildGradleConfiguration.legacy2, + firebaseCorePubSpec.performanceGradlePluginVersion, ); } @@ -274,16 +277,19 @@ Future gradleContentUpdates( flutterApp, content, BuildGradleConfiguration.latest, + firebaseCorePubSpec.googleServicesGradlePluginVersion, ); content = _applyCrashlyticsPlugin( flutterApp, content, BuildGradleConfiguration.latest, + firebaseCorePubSpec.crashlyticsGradlePluginVersion, ); content = _applyPerformancePlugin( flutterApp, content, BuildGradleConfiguration.latest, + firebaseCorePubSpec.performanceGradlePluginVersion, ); // WRITE /android/settings.gradle. We only need to do this with latest Flutter version >= 3.16.5 @@ -303,6 +309,7 @@ Future gradleContentUpdates( AndroidGradleContents _legacyUpdateAndroidBuildGradle( AndroidGradleContents content, + String googleServicesGradlePluginVersion, ) { var androidBuildGradleFileContents = content.buildGradleContent; @@ -327,7 +334,9 @@ AndroidGradleContents _legacyUpdateAndroidBuildGradle( androidBuildGradleFileContents = androidBuildGradleFileContents .replaceFirstMapped(_androidBuildGradleRegex, (match) { const indentation = ' '; - return '${match.group(0)}\n$indentation$_flutterFireConfigCommentStart\n$indentation$_googleServicesPlugin\n$indentation$_flutterFireConfigCommentEnd'; + final googleServicesPlugin = + "classpath '$_googleServicesPluginClass:$googleServicesGradlePluginVersion'"; + return '${match.group(0)}\n$indentation$_flutterFireConfigCommentStart\n$indentation$googleServicesPlugin\n$indentation$_flutterFireConfigCommentEnd'; }); return AndroidGradleContents( @@ -341,6 +350,7 @@ AndroidGradleContents _applyGoogleServicesPlugin( FlutterApp flutterApp, AndroidGradleContents content, BuildGradleConfiguration buildGradleConfiguration, + String googleServicesGradlePluginVersion, ) { var androidBuildGradleFileContents = content.buildGradleContent; var androidAppBuildGradleFileContents = content.appBuildGradleContent; @@ -348,7 +358,7 @@ AndroidGradleContents _applyGoogleServicesPlugin( if (buildGradleConfiguration == BuildGradleConfiguration.legacy1 || buildGradleConfiguration == BuildGradleConfiguration.legacy2) { - final updatedContent = _legacyUpdateAndroidBuildGradle(content); + final updatedContent = _legacyUpdateAndroidBuildGradle(content, googleServicesGradlePluginVersion); androidBuildGradleFileContents = updatedContent.buildGradleContent; } @@ -408,7 +418,7 @@ AndroidGradleContents _applyGoogleServicesPlugin( final endIndex = match.end; final toInsert = _applyGradleSettingsDependency( _googleServicesPluginName, - _googleServicesPluginVersion, + googleServicesGradlePluginVersion, flutterfireComments: true, ); @@ -431,13 +441,14 @@ AndroidGradleContents _applyCrashlyticsPlugin( FlutterApp flutterApp, AndroidGradleContents content, BuildGradleConfiguration buildGradleConfiguration, + String crashlyticsGradlePluginVersion, ) { // do not apply if firebase_crashlytics is not present if (!flutterApp.dependsOnPackage('firebase_crashlytics')) return content; return _applyFirebaseAndroidPlugin( pluginClassPath: _crashlyticsPluginClassPath, - pluginClassPathVersion: _crashlyticsPluginClassPathVersion, + pluginClassPathVersion: crashlyticsGradlePluginVersion, pluginClass: _crashlyticsPluginClass, content: content, buildGradleConfiguration: buildGradleConfiguration, @@ -448,13 +459,14 @@ AndroidGradleContents _applyPerformancePlugin( FlutterApp flutterApp, AndroidGradleContents content, BuildGradleConfiguration buildGradleConfiguration, + String performanceGradlePluginVersion, ) { // do not apply if firebase_performance is not present if (!flutterApp.dependsOnPackage('firebase_performance')) return content; return _applyFirebaseAndroidPlugin( pluginClassPath: _performancePluginClassPath, - pluginClassPathVersion: _performancePluginClassPathVersion, + pluginClassPathVersion: performanceGradlePluginVersion, pluginClass: _performancePluginClass, content: content, buildGradleConfiguration: buildGradleConfiguration, @@ -576,3 +588,39 @@ AndroidGradleContents _applyFirebaseAndroidPlugin({ gradleSettingsContent: androidGradleSettingsFileContents, ); } + +Future getFirebaseCorePubSpec() async { + final pubCacheFolder = _getPubCacheDirectory(); + final items = pubCacheFolder.listSync(); + final firebaseCoreDirectory = items + .whereType() + .where((e) => e.path.split('/').last.startsWith('firebase_core-')) + .sortedBy((d) => d.path) + .last; + + final firebaseCorePubspecFile = + pubspecPathForDirectory(firebaseCoreDirectory); + final pubSpec = await PubSpec.loadFile(firebaseCorePubspecFile); + final unparsedJson = pubSpec.unParsedYaml?['firebase'] as YamlMap?; + if (unparsedJson == null) { + throw Exception('Could not parse firebase_core pubspec.yaml'); + } + + return FirebasePubSpecModel.fromJson(unparsedJson.cast()); +} + +Directory _getPubCacheDirectory() { + final env = Platform.environment; + + if (env.containsKey('PUB_CACHE')) { + return Directory(env['PUB_CACHE']!); + } else if (Platform.isWindows) { + return Directory( + path.join(env['LOCALAPPDATA']!, 'Pub', 'Cache', 'hosted', 'pub.dev'), + ); + } else { + return Directory( + path.join('${env['HOME']}/.pub-cache', 'hosted', 'pub.dev'), + ); + } +} diff --git a/packages/flutterfire_cli/lib/src/firebase/firebase_pubspec_model.dart b/packages/flutterfire_cli/lib/src/firebase/firebase_pubspec_model.dart new file mode 100644 index 00000000..2c6c62cb --- /dev/null +++ b/packages/flutterfire_cli/lib/src/firebase/firebase_pubspec_model.dart @@ -0,0 +1,19 @@ +class FirebasePubSpecModel { + const FirebasePubSpecModel({ + required this.googleServicesGradlePluginVersion, + required this.crashlyticsGradlePluginVersion, + required this.performanceGradlePluginVersion, + }); + + factory FirebasePubSpecModel.fromJson(Map json) { + return FirebasePubSpecModel( + googleServicesGradlePluginVersion: json['google_services_gradle_plugin_version'], + crashlyticsGradlePluginVersion: json['crashlytics_gradle_plugin_version'], + performanceGradlePluginVersion: json['performance_gradle_plugin_version'], + ); + } + + final String googleServicesGradlePluginVersion; + final String crashlyticsGradlePluginVersion; + final String performanceGradlePluginVersion; +} \ No newline at end of file