Skip to content

Commit

Permalink
refactor: try fetch options from resources only if options is null an…
Browse files Browse the repository at this point in the history
…d platform is Android
  • Loading branch information
Salakar committed May 3, 2022
1 parent 63a8b97 commit cd66e5b
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,39 +73,43 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
applicationContext = null;
}

private Task<Map<String, Object>> firebaseAppToMap(FirebaseApp firebaseApp) {
return Tasks.call(
cachedThreadPool,
() -> {
Map<String, Object> appMap = new HashMap<>();
Map<String, String> optionsMap = new HashMap<>();
FirebaseOptions options = firebaseApp.getOptions();
private Map<String, String> firebaseOptionsToMap(FirebaseOptions options) {
Map<String, String> optionsMap = new HashMap<>();

optionsMap.put(KEY_API_KEY, options.getApiKey());
optionsMap.put(KEY_APP_ID, options.getApplicationId());
optionsMap.put(KEY_API_KEY, options.getApiKey());
optionsMap.put(KEY_APP_ID, options.getApplicationId());

if (options.getGcmSenderId() != null) {
optionsMap.put(KEY_MESSAGING_SENDER_ID, options.getGcmSenderId());
}
if (options.getGcmSenderId() != null) {
optionsMap.put(KEY_MESSAGING_SENDER_ID, options.getGcmSenderId());
}

if (options.getProjectId() != null) {
optionsMap.put(KEY_PROJECT_ID, options.getProjectId());
}
if (options.getProjectId() != null) {
optionsMap.put(KEY_PROJECT_ID, options.getProjectId());
}

if (options.getDatabaseUrl() != null) {
optionsMap.put(KEY_DATABASE_URL, options.getDatabaseUrl());
}
if (options.getDatabaseUrl() != null) {
optionsMap.put(KEY_DATABASE_URL, options.getDatabaseUrl());
}

if (options.getStorageBucket() != null) {
optionsMap.put(KEY_STORAGE_BUCKET, options.getStorageBucket());
}
if (options.getStorageBucket() != null) {
optionsMap.put(KEY_STORAGE_BUCKET, options.getStorageBucket());
}

if (options.getGaTrackingId() != null) {
optionsMap.put(KEY_TRACKING_ID, options.getGaTrackingId());
}
if (options.getGaTrackingId() != null) {
optionsMap.put(KEY_TRACKING_ID, options.getGaTrackingId());
}

return optionsMap;
}

private Task<Map<String, Object>> firebaseAppToMap(FirebaseApp firebaseApp) {
return Tasks.call(
cachedThreadPool,
() -> {
Map<String, Object> appMap = new HashMap<>();

appMap.put(KEY_NAME, firebaseApp.getName());
appMap.put(KEY_OPTIONS, optionsMap);
appMap.put(KEY_OPTIONS, firebaseOptionsToMap(firebaseApp.getOptions()));

appMap.put(
KEY_IS_AUTOMATIC_DATA_COLLECTION_ENABLED,
Expand All @@ -126,14 +130,10 @@ private Task<Map<String, Object>> initializeApp(Map<String, Object> arguments) {
String name = (String) Objects.requireNonNull(arguments.get(KEY_APP_NAME));

@SuppressWarnings("unchecked")
Map<String, String> optionsMap = (Map<String, String>) arguments.get(KEY_OPTIONS);
Map<String, String> optionsMap =
(Map<String, String>) Objects.requireNonNull(arguments.get(KEY_OPTIONS));

FirebaseOptions options;

if (optionsMap == null) {
options = FirebaseOptions.fromResource(applicationContext);
} else {
options =
FirebaseOptions options =
new FirebaseOptions.Builder()
.setApiKey(Objects.requireNonNull(optionsMap.get(KEY_API_KEY)))
.setApplicationId(Objects.requireNonNull(optionsMap.get(KEY_APP_ID)))
Expand All @@ -143,7 +143,6 @@ private Task<Map<String, Object>> initializeApp(Map<String, Object> arguments) {
.setStorageBucket(optionsMap.get(KEY_STORAGE_BUCKET))
.setGaTrackingId(optionsMap.get(KEY_TRACKING_ID))
.build();
}
// TODO(Salakar) hacky workaround a bug with FirebaseInAppMessaging causing the error:
// Can't create handler inside thread Thread[pool-3-thread-1,5,main] that has not called Looper.prepare()
// at com.google.firebase.inappmessaging.internal.ForegroundNotifier.<init>(ForegroundNotifier.java:61)
Expand Down Expand Up @@ -178,6 +177,16 @@ private Task<List<Map<String, Object>>> initializeCore() {
});
}

private Task<Map<String, String>> firebaseOptionsFromResource() {
return Tasks.call(
cachedThreadPool,
() -> {
final FirebaseOptions options = FirebaseOptions.fromResource(applicationContext);
if (options == null) return null;
return firebaseOptionsToMap(options);
});
}

private Task<Void> setAutomaticDataCollectionEnabled(Map<String, Object> arguments) {
return Tasks.call(
cachedThreadPool,
Expand Down Expand Up @@ -229,6 +238,9 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re
case "Firebase#initializeCore":
methodCallTask = initializeCore();
break;
case "Firebase#optionsFromResource":
methodCallTask = firebaseOptionsFromResource();
break;
case "FirebaseApp#setAutomaticDataCollectionEnabled":
methodCallTask = setAutomaticDataCollectionEnabled(call.arguments());
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,55 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 29

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
applicationId "io.flutter.plugins.firebasecoreexample"
minSdkVersion 21
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
compileSdkVersion flutter.compileSdkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
applicationId "io.flutter.plugins.firebasecoreexample"
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

buildTypes {
release {
signingConfig signingConfigs.debug
}
}
}

flutter {
source '../..'
source '../..'
}

dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
org.gradle.daemon=true
org.gradle.caching=true
org.gradle.parallel=true
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
include ':app'

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()

def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }

plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
Original file line number Diff line number Diff line change
Expand Up @@ -79,36 +79,50 @@ class MethodChannelFirebase extends FirebasePlatform {
if (name == null || name == defaultFirebaseAppName) {
MethodChannelFirebaseApp? defaultApp =
appInstances[defaultFirebaseAppName];
FirebaseOptions? _options = options;
// If no default app and no options are provided then
// attempt to read options from native resources on Android,
// e.g. this calls to `FirebaseOptions.fromResource(context)`.
if (defaultTargetPlatform == TargetPlatform.android &&
defaultApp == null &&
_options == null) {
final optionsMap = await channel.invokeMapMethod(
'Firebase#optionsFromResource',
);
if (optionsMap != null) {
_options = FirebaseOptions.fromMap(optionsMap);
}
}

// If no default app has been setup, the user is
// trying to initialize default from dart
if (defaultApp == null) {
// If no options are present & no default app has been setup, the user is
// trying to initialize default from Dart
if (defaultApp == null && _options != null) {
_initializeFirebaseAppFromMap((await channel.invokeMapMethod(
'Firebase#initializeApp',
<String, dynamic>{
'appName': defaultFirebaseAppName,
'options': options?.asMap
'options': _options.asMap
},
))!);
defaultApp = appInstances[defaultFirebaseAppName];
}

// If there is no native default app and the user didnt provide options to
// If there is no native default app and the user didn't provide options to
// create one, throw.
if (defaultApp == null && options == null) {
if (defaultApp == null && _options == null) {
throw coreNotInitialized();
}

// If there is a native default app and the user provided options do a soft
// check to see if options are roughly identical (so we don't unnecessarily
// throw on minor differences such as platform specific keys missing
// e.g. hot reloads/restarts).
if (defaultApp != null && options != null) {
if (options.apiKey != defaultApp.options.apiKey ||
(options.databaseURL != null &&
options.databaseURL != defaultApp.options.databaseURL) ||
(options.storageBucket != null &&
options.storageBucket != defaultApp.options.storageBucket)) {
if (defaultApp != null && _options != null) {
if (_options.apiKey != defaultApp.options.apiKey ||
(_options.databaseURL != null &&
_options.databaseURL != defaultApp.options.databaseURL) ||
(_options.storageBucket != null &&
_options.storageBucket != defaultApp.options.storageBucket)) {
// Options are different; throw.
throw duplicateApp(defaultFirebaseAppName);
}
Expand Down

0 comments on commit cd66e5b

Please sign in to comment.