From d00e5b9ca5552b2fa12b3d452f828d3fb4dff474 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 15:06:21 -0700 Subject: [PATCH 01/11] migrate --- .../FirebaseRemoteConfigPlugin.java | 190 ++---------------- .../MethodCallHandlerImpl.java | 181 +++++++++++++++++ .../android/app/src/main/AndroidManifest.xml | 11 +- .../EmbeddingV1Activity.java | 13 ++ .../MainActivity.java | 13 +- .../example/android/gradle.properties | 3 + .../example/lib/main.dart | 1 + 7 files changed, 234 insertions(+), 178 deletions(-) create mode 100644 packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java create mode 100644 packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java index d07a9ad1d57a..2db9b16bb827 100644 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java @@ -5,192 +5,40 @@ package io.flutter.plugins.firebase.firebaseremoteconfig; import android.content.Context; -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.remoteconfig.FirebaseRemoteConfig; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; -import io.flutter.plugin.common.MethodCall; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; /** FirebaseRemoteConfigPlugin */ -public class FirebaseRemoteConfigPlugin implements MethodCallHandler { +public class FirebaseRemoteConfigPlugin implements FlutterPlugin { - public static final String TAG = "FirebaseRemoteConfigPlugin"; - public static final String PREFS_NAME = + static final String TAG = "FirebaseRemoteConfigPlugin"; + static final String PREFS_NAME = "io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin"; - public static final String DEFAULT_PREF_KEY = "default_keys"; + static final String METHOD_CHANNEL = "plugins.flutter.io/firebase_remote_config"; - private static SharedPreferences sharedPreferences; + private MethodChannel channel; public static void registerWith(Registrar registrar) { - final MethodChannel channel = - new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_remote_config"); - channel.setMethodCallHandler(new FirebaseRemoteConfigPlugin()); - sharedPreferences = registrar.context().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + FirebaseRemoteConfigPlugin plugin = new FirebaseRemoteConfigPlugin(); + plugin.setupChannel(registrar.messenger(), registrar.context()); } @Override - public void onMethodCall(MethodCall call, final Result result) { - switch (call.method) { - case "RemoteConfig#instance": - { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - FirebaseRemoteConfig.getInstance().getInfo(); - - Map properties = new HashMap<>(); - properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - properties.put( - "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); - properties.put("parameters", getConfigParameters()); - result.success(properties); - break; - } - case "RemoteConfig#setConfigSettings": - { - boolean debugMode = call.argument("debugMode"); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - FirebaseRemoteConfigSettings settings = - new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); - firebaseRemoteConfig.setConfigSettings(settings); - result.success(null); - break; - } - case "RemoteConfig#fetch": - { - long expiration = ((Number) call.argument("expiration")).longValue(); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - firebaseRemoteConfig - .fetch(expiration) - .addOnCompleteListener( - new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - firebaseRemoteConfig.getInfo(); - Map properties = new HashMap<>(); - properties.put( - "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", - mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - if (!task.isSuccessful()) { - final Exception exception = task.getException(); - - if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { - properties.put( - "fetchThrottledEnd", - ((FirebaseRemoteConfigFetchThrottledException) exception) - .getThrottleEndTimeMillis()); - String errorMessage = - "Fetch has been throttled. See the error's " - + "FETCH_THROTTLED_END field for throttle end time."; - result.error("fetchFailedThrottled", errorMessage, properties); - } else { - String errorMessage = - "Unable to complete fetch. Reason is unknown " - + "but this could be due to lack of connectivity."; - result.error("fetchFailed", errorMessage, properties); - } - } else { - result.success(properties); - } - } - }); - break; - } - case "RemoteConfig#activate": - { - boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); - Map properties = new HashMap<>(); - properties.put("parameters", getConfigParameters()); - properties.put("newConfig", newConfig); - result.success(properties); - break; - } - case "RemoteConfig#setDefaults": - { - Map defaults = call.argument("defaults"); - FirebaseRemoteConfig.getInstance().setDefaults(defaults); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); - result.success(null); - break; - } - default: - { - result.notImplemented(); - break; - } - } - } - - private Map getConfigParameters() { - FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - Map parameterMap = new HashMap<>(); - Set keys = firebaseRemoteConfig.getKeysByPrefix(""); - for (String key : keys) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); - parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); - } - // Add default parameters if missing since `getKeysByPrefix` does not return default keys. - Set defaultKeys = - sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); - for (String defaultKey : defaultKeys) { - if (!parameterMap.containsKey(defaultKey)) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); - parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); - } - } - return parameterMap; + public void onAttachedToEngine(FlutterPluginBinding binding) { + setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); } - private Map createRemoteConfigValueMap( - FirebaseRemoteConfigValue remoteConfigValue) { - Map valueMap = new HashMap<>(); - valueMap.put("value", remoteConfigValue.asByteArray()); - valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); - return valueMap; - } - - private String mapLastFetchStatus(int status) { - switch (status) { - case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: - return "success"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: - return "failure"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: - return "throttled"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: - return "noFetchYet"; - default: - return "failure"; - } + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + channel = null; } - private String mapValueSource(int source) { - switch (source) { - case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: - return "static"; - case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: - return "default"; - case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: - return "remote"; - default: - return "static"; - } + private void setupChannel(BinaryMessenger messenger, Context context) { + MethodCallHandlerImpl handler = + new MethodCallHandlerImpl(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)); + channel = new MethodChannel(messenger, METHOD_CHANNEL); + channel.setMethodCallHandler(handler); } } diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java new file mode 100644 index 000000000000..5c59bad7f116 --- /dev/null +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java @@ -0,0 +1,181 @@ +package io.flutter.plugins.firebase.firebaseremoteconfig; + +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.remoteconfig.FirebaseRemoteConfig; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { + + private static final String DEFAULT_PREF_KEY = "default_keys"; + + private static SharedPreferences sharedPreferences; + + MethodCallHandlerImpl(@NonNull SharedPreferences sharedPreferences) { + this.sharedPreferences = sharedPreferences; + } + + @Override + public void onMethodCall(MethodCall call, final MethodChannel.Result result) { + switch (call.method) { + case "RemoteConfig#instance": + { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + FirebaseRemoteConfig.getInstance().getInfo(); + + Map properties = new HashMap<>(); + properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + properties.put( + "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); + properties.put("parameters", getConfigParameters()); + result.success(properties); + break; + } + case "RemoteConfig#setConfigSettings": + { + boolean debugMode = call.argument("debugMode"); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + FirebaseRemoteConfigSettings settings = + new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); + firebaseRemoteConfig.setConfigSettings(settings); + result.success(null); + break; + } + case "RemoteConfig#fetch": + { + long expiration = ((Number) call.argument("expiration")).longValue(); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + firebaseRemoteConfig + .fetch(expiration) + .addOnCompleteListener( + new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + firebaseRemoteConfig.getInfo(); + Map properties = new HashMap<>(); + properties.put( + "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", + mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + if (!task.isSuccessful()) { + final Exception exception = task.getException(); + + if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { + properties.put( + "fetchThrottledEnd", + ((FirebaseRemoteConfigFetchThrottledException) exception) + .getThrottleEndTimeMillis()); + String errorMessage = + "Fetch has been throttled. See the error's " + + "FETCH_THROTTLED_END field for throttle end time."; + result.error("fetchFailedThrottled", errorMessage, properties); + } else { + String errorMessage = + "Unable to complete fetch. Reason is unknown " + + "but this could be due to lack of connectivity."; + result.error("fetchFailed", errorMessage, properties); + } + } else { + result.success(properties); + } + } + }); + break; + } + case "RemoteConfig#activate": + { + boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); + Map properties = new HashMap<>(); + properties.put("parameters", getConfigParameters()); + properties.put("newConfig", newConfig); + result.success(properties); + break; + } + case "RemoteConfig#setDefaults": + { + Map defaults = call.argument("defaults"); + FirebaseRemoteConfig.getInstance().setDefaults(defaults); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); + result.success(null); + break; + } + default: + { + result.notImplemented(); + break; + } + } + } + + private Map getConfigParameters() { + FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + Map parameterMap = new HashMap<>(); + Set keys = firebaseRemoteConfig.getKeysByPrefix(""); + for (String key : keys) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); + parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); + } + // Add default parameters if missing since `getKeysByPrefix` does not return default keys. + Set defaultKeys = + sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); + for (String defaultKey : defaultKeys) { + if (!parameterMap.containsKey(defaultKey)) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); + parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); + } + } + return parameterMap; + } + + private Map createRemoteConfigValueMap( + FirebaseRemoteConfigValue remoteConfigValue) { + Map valueMap = new HashMap<>(); + valueMap.put("value", remoteConfigValue.asByteArray()); + valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); + return valueMap; + } + + private String mapLastFetchStatus(int status) { + switch (status) { + case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: + return "success"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: + return "failure"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: + return "throttled"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: + return "noFetchYet"; + default: + return "failure"; + } + } + + private String mapValueSource(int source) { + switch (source) { + case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: + return "static"; + case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: + return "default"; + case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: + return "remote"; + default: + return "static"; + } + } +} diff --git a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml index fe4292fe0322..7100b12a4e6e 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml @@ -17,8 +17,9 @@ android:label="firebase_remote_config_example" android:icon="@mipmap/ic_launcher"> + + diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java new file mode 100644 index 000000000000..2af625cab23d --- /dev/null +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java @@ -0,0 +1,13 @@ +package io.flutter.plugins.firebase.firebaseremoteconfigexample; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class EmbeddingV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java index ef048c74f4df..a03548b6e845 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java @@ -1,13 +1,14 @@ package io.flutter.plugins.firebase.firebaseremoteconfigexample; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin; public class MainActivity extends FlutterActivity { + @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); + public void configureFlutterEngine(FlutterEngine flutterEngine) { + super.configureFlutterEngine(flutterEngine); + flutterEngine.getPlugins().add(new FirebaseRemoteConfigPlugin()); } } diff --git a/packages/firebase_remote_config/example/android/gradle.properties b/packages/firebase_remote_config/example/android/gradle.properties index 8bd86f680510..a5965ab8dced 100644 --- a/packages/firebase_remote_config/example/android/gradle.properties +++ b/packages/firebase_remote_config/example/android/gradle.properties @@ -1 +1,4 @@ org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/packages/firebase_remote_config/example/lib/main.dart b/packages/firebase_remote_config/example/lib/main.dart index 8db737372086..89a7d6de387e 100644 --- a/packages/firebase_remote_config/example/lib/main.dart +++ b/packages/firebase_remote_config/example/lib/main.dart @@ -8,6 +8,7 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/material.dart'; void main() { + WidgetsFlutterBinding.ensureInitialized(); runApp(MaterialApp( title: 'Remote Config Example', home: FutureBuilder( From 78c882890126ba6788006cee9b042c7b3daecf67 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 15:07:37 -0700 Subject: [PATCH 02/11] migrate --- .../FirebaseRemoteConfigPlugin.java | 190 ++++++++++++++++-- .../MethodCallHandlerImpl.java | 181 ----------------- .../android/app/src/main/AndroidManifest.xml | 11 +- .../EmbeddingV1Activity.java | 13 -- .../MainActivity.java | 13 +- .../example/android/gradle.properties | 3 - .../example/lib/main.dart | 1 - 7 files changed, 178 insertions(+), 234 deletions(-) delete mode 100644 packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java delete mode 100644 packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java index 2db9b16bb827..d07a9ad1d57a 100644 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java @@ -5,40 +5,192 @@ package io.flutter.plugins.firebase.firebaseremoteconfig; import android.content.Context; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.remoteconfig.FirebaseRemoteConfig; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; +import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** FirebaseRemoteConfigPlugin */ -public class FirebaseRemoteConfigPlugin implements FlutterPlugin { +public class FirebaseRemoteConfigPlugin implements MethodCallHandler { - static final String TAG = "FirebaseRemoteConfigPlugin"; - static final String PREFS_NAME = + public static final String TAG = "FirebaseRemoteConfigPlugin"; + public static final String PREFS_NAME = "io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin"; - static final String METHOD_CHANNEL = "plugins.flutter.io/firebase_remote_config"; + public static final String DEFAULT_PREF_KEY = "default_keys"; - private MethodChannel channel; + private static SharedPreferences sharedPreferences; public static void registerWith(Registrar registrar) { - FirebaseRemoteConfigPlugin plugin = new FirebaseRemoteConfigPlugin(); - plugin.setupChannel(registrar.messenger(), registrar.context()); + final MethodChannel channel = + new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_remote_config"); + channel.setMethodCallHandler(new FirebaseRemoteConfigPlugin()); + sharedPreferences = registrar.context().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); } @Override - public void onAttachedToEngine(FlutterPluginBinding binding) { - setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); + public void onMethodCall(MethodCall call, final Result result) { + switch (call.method) { + case "RemoteConfig#instance": + { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + FirebaseRemoteConfig.getInstance().getInfo(); + + Map properties = new HashMap<>(); + properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + properties.put( + "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); + properties.put("parameters", getConfigParameters()); + result.success(properties); + break; + } + case "RemoteConfig#setConfigSettings": + { + boolean debugMode = call.argument("debugMode"); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + FirebaseRemoteConfigSettings settings = + new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); + firebaseRemoteConfig.setConfigSettings(settings); + result.success(null); + break; + } + case "RemoteConfig#fetch": + { + long expiration = ((Number) call.argument("expiration")).longValue(); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + firebaseRemoteConfig + .fetch(expiration) + .addOnCompleteListener( + new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + firebaseRemoteConfig.getInfo(); + Map properties = new HashMap<>(); + properties.put( + "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", + mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + if (!task.isSuccessful()) { + final Exception exception = task.getException(); + + if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { + properties.put( + "fetchThrottledEnd", + ((FirebaseRemoteConfigFetchThrottledException) exception) + .getThrottleEndTimeMillis()); + String errorMessage = + "Fetch has been throttled. See the error's " + + "FETCH_THROTTLED_END field for throttle end time."; + result.error("fetchFailedThrottled", errorMessage, properties); + } else { + String errorMessage = + "Unable to complete fetch. Reason is unknown " + + "but this could be due to lack of connectivity."; + result.error("fetchFailed", errorMessage, properties); + } + } else { + result.success(properties); + } + } + }); + break; + } + case "RemoteConfig#activate": + { + boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); + Map properties = new HashMap<>(); + properties.put("parameters", getConfigParameters()); + properties.put("newConfig", newConfig); + result.success(properties); + break; + } + case "RemoteConfig#setDefaults": + { + Map defaults = call.argument("defaults"); + FirebaseRemoteConfig.getInstance().setDefaults(defaults); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); + result.success(null); + break; + } + default: + { + result.notImplemented(); + break; + } + } } - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) { - channel = null; + private Map getConfigParameters() { + FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + Map parameterMap = new HashMap<>(); + Set keys = firebaseRemoteConfig.getKeysByPrefix(""); + for (String key : keys) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); + parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); + } + // Add default parameters if missing since `getKeysByPrefix` does not return default keys. + Set defaultKeys = + sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); + for (String defaultKey : defaultKeys) { + if (!parameterMap.containsKey(defaultKey)) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); + parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); + } + } + return parameterMap; + } + + private Map createRemoteConfigValueMap( + FirebaseRemoteConfigValue remoteConfigValue) { + Map valueMap = new HashMap<>(); + valueMap.put("value", remoteConfigValue.asByteArray()); + valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); + return valueMap; + } + + private String mapLastFetchStatus(int status) { + switch (status) { + case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: + return "success"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: + return "failure"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: + return "throttled"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: + return "noFetchYet"; + default: + return "failure"; + } } - private void setupChannel(BinaryMessenger messenger, Context context) { - MethodCallHandlerImpl handler = - new MethodCallHandlerImpl(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)); - channel = new MethodChannel(messenger, METHOD_CHANNEL); - channel.setMethodCallHandler(handler); + private String mapValueSource(int source) { + switch (source) { + case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: + return "static"; + case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: + return "default"; + case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: + return "remote"; + default: + return "static"; + } } } diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java deleted file mode 100644 index 5c59bad7f116..000000000000 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package io.flutter.plugins.firebase.firebaseremoteconfig; - -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.remoteconfig.FirebaseRemoteConfig; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - - private static final String DEFAULT_PREF_KEY = "default_keys"; - - private static SharedPreferences sharedPreferences; - - MethodCallHandlerImpl(@NonNull SharedPreferences sharedPreferences) { - this.sharedPreferences = sharedPreferences; - } - - @Override - public void onMethodCall(MethodCall call, final MethodChannel.Result result) { - switch (call.method) { - case "RemoteConfig#instance": - { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - FirebaseRemoteConfig.getInstance().getInfo(); - - Map properties = new HashMap<>(); - properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - properties.put( - "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); - properties.put("parameters", getConfigParameters()); - result.success(properties); - break; - } - case "RemoteConfig#setConfigSettings": - { - boolean debugMode = call.argument("debugMode"); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - FirebaseRemoteConfigSettings settings = - new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); - firebaseRemoteConfig.setConfigSettings(settings); - result.success(null); - break; - } - case "RemoteConfig#fetch": - { - long expiration = ((Number) call.argument("expiration")).longValue(); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - firebaseRemoteConfig - .fetch(expiration) - .addOnCompleteListener( - new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - firebaseRemoteConfig.getInfo(); - Map properties = new HashMap<>(); - properties.put( - "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", - mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - if (!task.isSuccessful()) { - final Exception exception = task.getException(); - - if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { - properties.put( - "fetchThrottledEnd", - ((FirebaseRemoteConfigFetchThrottledException) exception) - .getThrottleEndTimeMillis()); - String errorMessage = - "Fetch has been throttled. See the error's " - + "FETCH_THROTTLED_END field for throttle end time."; - result.error("fetchFailedThrottled", errorMessage, properties); - } else { - String errorMessage = - "Unable to complete fetch. Reason is unknown " - + "but this could be due to lack of connectivity."; - result.error("fetchFailed", errorMessage, properties); - } - } else { - result.success(properties); - } - } - }); - break; - } - case "RemoteConfig#activate": - { - boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); - Map properties = new HashMap<>(); - properties.put("parameters", getConfigParameters()); - properties.put("newConfig", newConfig); - result.success(properties); - break; - } - case "RemoteConfig#setDefaults": - { - Map defaults = call.argument("defaults"); - FirebaseRemoteConfig.getInstance().setDefaults(defaults); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); - result.success(null); - break; - } - default: - { - result.notImplemented(); - break; - } - } - } - - private Map getConfigParameters() { - FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - Map parameterMap = new HashMap<>(); - Set keys = firebaseRemoteConfig.getKeysByPrefix(""); - for (String key : keys) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); - parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); - } - // Add default parameters if missing since `getKeysByPrefix` does not return default keys. - Set defaultKeys = - sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); - for (String defaultKey : defaultKeys) { - if (!parameterMap.containsKey(defaultKey)) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); - parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); - } - } - return parameterMap; - } - - private Map createRemoteConfigValueMap( - FirebaseRemoteConfigValue remoteConfigValue) { - Map valueMap = new HashMap<>(); - valueMap.put("value", remoteConfigValue.asByteArray()); - valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); - return valueMap; - } - - private String mapLastFetchStatus(int status) { - switch (status) { - case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: - return "success"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: - return "failure"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: - return "throttled"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: - return "noFetchYet"; - default: - return "failure"; - } - } - - private String mapValueSource(int source) { - switch (source) { - case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: - return "static"; - case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: - return "default"; - case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: - return "remote"; - default: - return "static"; - } - } -} diff --git a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml index 7100b12a4e6e..fe4292fe0322 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml @@ -17,9 +17,8 @@ android:label="firebase_remote_config_example" android:icon="@mipmap/ic_launcher"> - - diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java deleted file mode 100644 index 2af625cab23d..000000000000 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.flutter.plugins.firebase.firebaseremoteconfigexample; - -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; - -public class EmbeddingV1Activity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java index a03548b6e845..ef048c74f4df 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java @@ -1,14 +1,13 @@ package io.flutter.plugins.firebase.firebaseremoteconfigexample; -import io.flutter.embedding.android.FlutterActivity; -import io.flutter.embedding.engine.FlutterEngine; -import io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin; +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { - @Override - public void configureFlutterEngine(FlutterEngine flutterEngine) { - super.configureFlutterEngine(flutterEngine); - flutterEngine.getPlugins().add(new FirebaseRemoteConfigPlugin()); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); } } diff --git a/packages/firebase_remote_config/example/android/gradle.properties b/packages/firebase_remote_config/example/android/gradle.properties index a5965ab8dced..8bd86f680510 100644 --- a/packages/firebase_remote_config/example/android/gradle.properties +++ b/packages/firebase_remote_config/example/android/gradle.properties @@ -1,4 +1 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file diff --git a/packages/firebase_remote_config/example/lib/main.dart b/packages/firebase_remote_config/example/lib/main.dart index 89a7d6de387e..8db737372086 100644 --- a/packages/firebase_remote_config/example/lib/main.dart +++ b/packages/firebase_remote_config/example/lib/main.dart @@ -8,7 +8,6 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/material.dart'; void main() { - WidgetsFlutterBinding.ensureInitialized(); runApp(MaterialApp( title: 'Remote Config Example', home: FutureBuilder( From 839defa34fc13abeee60fb1c7917b404122aa073 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 15:09:31 -0700 Subject: [PATCH 03/11] Revert "migrate" This reverts commit 78c882890126ba6788006cee9b042c7b3daecf67. --- .../FirebaseRemoteConfigPlugin.java | 190 ++---------------- .../MethodCallHandlerImpl.java | 181 +++++++++++++++++ .../android/app/src/main/AndroidManifest.xml | 11 +- .../EmbeddingV1Activity.java | 13 ++ .../MainActivity.java | 13 +- .../example/android/gradle.properties | 3 + .../example/lib/main.dart | 1 + 7 files changed, 234 insertions(+), 178 deletions(-) create mode 100644 packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java create mode 100644 packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java index d07a9ad1d57a..2db9b16bb827 100644 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java @@ -5,192 +5,40 @@ package io.flutter.plugins.firebase.firebaseremoteconfig; import android.content.Context; -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.remoteconfig.FirebaseRemoteConfig; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; -import io.flutter.plugin.common.MethodCall; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; /** FirebaseRemoteConfigPlugin */ -public class FirebaseRemoteConfigPlugin implements MethodCallHandler { +public class FirebaseRemoteConfigPlugin implements FlutterPlugin { - public static final String TAG = "FirebaseRemoteConfigPlugin"; - public static final String PREFS_NAME = + static final String TAG = "FirebaseRemoteConfigPlugin"; + static final String PREFS_NAME = "io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin"; - public static final String DEFAULT_PREF_KEY = "default_keys"; + static final String METHOD_CHANNEL = "plugins.flutter.io/firebase_remote_config"; - private static SharedPreferences sharedPreferences; + private MethodChannel channel; public static void registerWith(Registrar registrar) { - final MethodChannel channel = - new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_remote_config"); - channel.setMethodCallHandler(new FirebaseRemoteConfigPlugin()); - sharedPreferences = registrar.context().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + FirebaseRemoteConfigPlugin plugin = new FirebaseRemoteConfigPlugin(); + plugin.setupChannel(registrar.messenger(), registrar.context()); } @Override - public void onMethodCall(MethodCall call, final Result result) { - switch (call.method) { - case "RemoteConfig#instance": - { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - FirebaseRemoteConfig.getInstance().getInfo(); - - Map properties = new HashMap<>(); - properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - properties.put( - "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); - properties.put("parameters", getConfigParameters()); - result.success(properties); - break; - } - case "RemoteConfig#setConfigSettings": - { - boolean debugMode = call.argument("debugMode"); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - FirebaseRemoteConfigSettings settings = - new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); - firebaseRemoteConfig.setConfigSettings(settings); - result.success(null); - break; - } - case "RemoteConfig#fetch": - { - long expiration = ((Number) call.argument("expiration")).longValue(); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - firebaseRemoteConfig - .fetch(expiration) - .addOnCompleteListener( - new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - firebaseRemoteConfig.getInfo(); - Map properties = new HashMap<>(); - properties.put( - "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", - mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - if (!task.isSuccessful()) { - final Exception exception = task.getException(); - - if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { - properties.put( - "fetchThrottledEnd", - ((FirebaseRemoteConfigFetchThrottledException) exception) - .getThrottleEndTimeMillis()); - String errorMessage = - "Fetch has been throttled. See the error's " - + "FETCH_THROTTLED_END field for throttle end time."; - result.error("fetchFailedThrottled", errorMessage, properties); - } else { - String errorMessage = - "Unable to complete fetch. Reason is unknown " - + "but this could be due to lack of connectivity."; - result.error("fetchFailed", errorMessage, properties); - } - } else { - result.success(properties); - } - } - }); - break; - } - case "RemoteConfig#activate": - { - boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); - Map properties = new HashMap<>(); - properties.put("parameters", getConfigParameters()); - properties.put("newConfig", newConfig); - result.success(properties); - break; - } - case "RemoteConfig#setDefaults": - { - Map defaults = call.argument("defaults"); - FirebaseRemoteConfig.getInstance().setDefaults(defaults); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); - result.success(null); - break; - } - default: - { - result.notImplemented(); - break; - } - } - } - - private Map getConfigParameters() { - FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - Map parameterMap = new HashMap<>(); - Set keys = firebaseRemoteConfig.getKeysByPrefix(""); - for (String key : keys) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); - parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); - } - // Add default parameters if missing since `getKeysByPrefix` does not return default keys. - Set defaultKeys = - sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); - for (String defaultKey : defaultKeys) { - if (!parameterMap.containsKey(defaultKey)) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); - parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); - } - } - return parameterMap; + public void onAttachedToEngine(FlutterPluginBinding binding) { + setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); } - private Map createRemoteConfigValueMap( - FirebaseRemoteConfigValue remoteConfigValue) { - Map valueMap = new HashMap<>(); - valueMap.put("value", remoteConfigValue.asByteArray()); - valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); - return valueMap; - } - - private String mapLastFetchStatus(int status) { - switch (status) { - case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: - return "success"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: - return "failure"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: - return "throttled"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: - return "noFetchYet"; - default: - return "failure"; - } + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + channel = null; } - private String mapValueSource(int source) { - switch (source) { - case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: - return "static"; - case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: - return "default"; - case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: - return "remote"; - default: - return "static"; - } + private void setupChannel(BinaryMessenger messenger, Context context) { + MethodCallHandlerImpl handler = + new MethodCallHandlerImpl(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)); + channel = new MethodChannel(messenger, METHOD_CHANNEL); + channel.setMethodCallHandler(handler); } } diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java new file mode 100644 index 000000000000..5c59bad7f116 --- /dev/null +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java @@ -0,0 +1,181 @@ +package io.flutter.plugins.firebase.firebaseremoteconfig; + +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.remoteconfig.FirebaseRemoteConfig; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { + + private static final String DEFAULT_PREF_KEY = "default_keys"; + + private static SharedPreferences sharedPreferences; + + MethodCallHandlerImpl(@NonNull SharedPreferences sharedPreferences) { + this.sharedPreferences = sharedPreferences; + } + + @Override + public void onMethodCall(MethodCall call, final MethodChannel.Result result) { + switch (call.method) { + case "RemoteConfig#instance": + { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + FirebaseRemoteConfig.getInstance().getInfo(); + + Map properties = new HashMap<>(); + properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + properties.put( + "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); + properties.put("parameters", getConfigParameters()); + result.success(properties); + break; + } + case "RemoteConfig#setConfigSettings": + { + boolean debugMode = call.argument("debugMode"); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + FirebaseRemoteConfigSettings settings = + new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); + firebaseRemoteConfig.setConfigSettings(settings); + result.success(null); + break; + } + case "RemoteConfig#fetch": + { + long expiration = ((Number) call.argument("expiration")).longValue(); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + firebaseRemoteConfig + .fetch(expiration) + .addOnCompleteListener( + new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + firebaseRemoteConfig.getInfo(); + Map properties = new HashMap<>(); + properties.put( + "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", + mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + if (!task.isSuccessful()) { + final Exception exception = task.getException(); + + if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { + properties.put( + "fetchThrottledEnd", + ((FirebaseRemoteConfigFetchThrottledException) exception) + .getThrottleEndTimeMillis()); + String errorMessage = + "Fetch has been throttled. See the error's " + + "FETCH_THROTTLED_END field for throttle end time."; + result.error("fetchFailedThrottled", errorMessage, properties); + } else { + String errorMessage = + "Unable to complete fetch. Reason is unknown " + + "but this could be due to lack of connectivity."; + result.error("fetchFailed", errorMessage, properties); + } + } else { + result.success(properties); + } + } + }); + break; + } + case "RemoteConfig#activate": + { + boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); + Map properties = new HashMap<>(); + properties.put("parameters", getConfigParameters()); + properties.put("newConfig", newConfig); + result.success(properties); + break; + } + case "RemoteConfig#setDefaults": + { + Map defaults = call.argument("defaults"); + FirebaseRemoteConfig.getInstance().setDefaults(defaults); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); + result.success(null); + break; + } + default: + { + result.notImplemented(); + break; + } + } + } + + private Map getConfigParameters() { + FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + Map parameterMap = new HashMap<>(); + Set keys = firebaseRemoteConfig.getKeysByPrefix(""); + for (String key : keys) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); + parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); + } + // Add default parameters if missing since `getKeysByPrefix` does not return default keys. + Set defaultKeys = + sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); + for (String defaultKey : defaultKeys) { + if (!parameterMap.containsKey(defaultKey)) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); + parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); + } + } + return parameterMap; + } + + private Map createRemoteConfigValueMap( + FirebaseRemoteConfigValue remoteConfigValue) { + Map valueMap = new HashMap<>(); + valueMap.put("value", remoteConfigValue.asByteArray()); + valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); + return valueMap; + } + + private String mapLastFetchStatus(int status) { + switch (status) { + case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: + return "success"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: + return "failure"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: + return "throttled"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: + return "noFetchYet"; + default: + return "failure"; + } + } + + private String mapValueSource(int source) { + switch (source) { + case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: + return "static"; + case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: + return "default"; + case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: + return "remote"; + default: + return "static"; + } + } +} diff --git a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml index fe4292fe0322..7100b12a4e6e 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml @@ -17,8 +17,9 @@ android:label="firebase_remote_config_example" android:icon="@mipmap/ic_launcher"> + + diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java new file mode 100644 index 000000000000..2af625cab23d --- /dev/null +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java @@ -0,0 +1,13 @@ +package io.flutter.plugins.firebase.firebaseremoteconfigexample; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class EmbeddingV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java index ef048c74f4df..a03548b6e845 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java @@ -1,13 +1,14 @@ package io.flutter.plugins.firebase.firebaseremoteconfigexample; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin; public class MainActivity extends FlutterActivity { + @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); + public void configureFlutterEngine(FlutterEngine flutterEngine) { + super.configureFlutterEngine(flutterEngine); + flutterEngine.getPlugins().add(new FirebaseRemoteConfigPlugin()); } } diff --git a/packages/firebase_remote_config/example/android/gradle.properties b/packages/firebase_remote_config/example/android/gradle.properties index 8bd86f680510..a5965ab8dced 100644 --- a/packages/firebase_remote_config/example/android/gradle.properties +++ b/packages/firebase_remote_config/example/android/gradle.properties @@ -1 +1,4 @@ org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/packages/firebase_remote_config/example/lib/main.dart b/packages/firebase_remote_config/example/lib/main.dart index 8db737372086..89a7d6de387e 100644 --- a/packages/firebase_remote_config/example/lib/main.dart +++ b/packages/firebase_remote_config/example/lib/main.dart @@ -8,6 +8,7 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/material.dart'; void main() { + WidgetsFlutterBinding.ensureInitialized(); runApp(MaterialApp( title: 'Remote Config Example', home: FutureBuilder( From 46b97e8c8b1c92189bb607c6e9699eed2db38be4 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 15:13:34 -0700 Subject: [PATCH 04/11] add firebase core dependency in example app --- .../firebase/firebaseremoteconfigexample/MainActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java index a03548b6e845..078bb260ecf4 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java @@ -2,6 +2,8 @@ import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; +import io.flutter.plugins.firebase.core.FirebaseCorePlugin; import io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin; public class MainActivity extends FlutterActivity { @@ -10,5 +12,9 @@ public class MainActivity extends FlutterActivity { public void configureFlutterEngine(FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); flutterEngine.getPlugins().add(new FirebaseRemoteConfigPlugin()); + + ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine); + FirebaseCorePlugin.registerWith( + shimPluginRegistry.registrarFor("io.flutter.plugins.firebase.core.FirebaseCorePlugin")); } } From ab4a29855644bb81ff7f83a81217617ad8b3edc3 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 16:06:01 -0700 Subject: [PATCH 05/11] draft --- .../database/FirebaseDatabasePlugin.java | 500 +---------------- .../database/MethodCallHandlerImpl.java | 527 ++++++++++++++++++ .../android/app/src/main/AndroidManifest.xml | 10 +- .../EmbeddingV1Activity.java | 17 + .../firebasedatabaseexample/MainActivity.java | 23 +- .../example/android/gradle.properties | 1 + .../firebase_database/example/lib/main.dart | 1 + 7 files changed, 587 insertions(+), 492 deletions(-) create mode 100644 packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/MethodCallHandlerImpl.java create mode 100644 packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/EmbeddingV1Activity.java diff --git a/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java index 18911914764f..2cebad0a8cb1 100644 --- a/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java +++ b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java @@ -23,6 +23,9 @@ import com.google.firebase.database.Query; import com.google.firebase.database.Transaction; import com.google.firebase.database.ValueEventListener; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; @@ -35,498 +38,29 @@ import java.util.concurrent.TimeoutException; /** FirebaseDatabasePlugin */ -public class FirebaseDatabasePlugin implements MethodCallHandler { - - private static final String TAG = "FirebaseDatabasePlugin"; - - private final MethodChannel channel; - private final Handler handler = new Handler(); - private static final String EVENT_TYPE_CHILD_ADDED = "_EventType.childAdded"; - private static final String EVENT_TYPE_CHILD_REMOVED = "_EventType.childRemoved"; - private static final String EVENT_TYPE_CHILD_CHANGED = "_EventType.childChanged"; - private static final String EVENT_TYPE_CHILD_MOVED = "_EventType.childMoved"; - private static final String EVENT_TYPE_VALUE = "_EventType.value"; +public class FirebaseDatabasePlugin implements FlutterPlugin { - // Handles are ints used as indexes into the sparse array of active observers - private int nextHandle = 0; - private final SparseArray observers = new SparseArray<>(); + private MethodChannel channel; public static void registerWith(PluginRegistry.Registrar registrar) { - final MethodChannel channel = - new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_database"); - channel.setMethodCallHandler(new FirebaseDatabasePlugin(channel)); - } - - private FirebaseDatabasePlugin(MethodChannel channel) { - this.channel = channel; - } - - private DatabaseReference getReference(FirebaseDatabase database, Map arguments) { - String path = (String) arguments.get("path"); - DatabaseReference reference = database.getReference(); - if (path != null) reference = reference.child(path); - return reference; - } - - private Query getQuery(FirebaseDatabase database, Map arguments) { - Query query = getReference(database, arguments); - @SuppressWarnings("unchecked") - Map parameters = (Map) arguments.get("parameters"); - if (parameters == null) return query; - Object orderBy = parameters.get("orderBy"); - if ("child".equals(orderBy)) { - query = query.orderByChild((String) parameters.get("orderByChildKey")); - } else if ("key".equals(orderBy)) { - query = query.orderByKey(); - } else if ("value".equals(orderBy)) { - query = query.orderByValue(); - } else if ("priority".equals(orderBy)) { - query = query.orderByPriority(); - } - if (parameters.containsKey("startAt")) { - Object startAt = parameters.get("startAt"); - if (parameters.containsKey("startAtKey")) { - String startAtKey = (String) parameters.get("startAtKey"); - if (startAt instanceof Boolean) { - query = query.startAt((Boolean) startAt, startAtKey); - } else if (startAt instanceof Number) { - query = query.startAt(((Number) startAt).doubleValue(), startAtKey); - } else { - query = query.startAt((String) startAt, startAtKey); - } - } else { - if (startAt instanceof Boolean) { - query = query.startAt((Boolean) startAt); - } else if (startAt instanceof Number) { - query = query.startAt(((Number) startAt).doubleValue()); - } else { - query = query.startAt((String) startAt); - } - } - } - if (parameters.containsKey("endAt")) { - Object endAt = parameters.get("endAt"); - if (parameters.containsKey("endAtKey")) { - String endAtKey = (String) parameters.get("endAtKey"); - if (endAt instanceof Boolean) { - query = query.endAt((Boolean) endAt, endAtKey); - } else if (endAt instanceof Number) { - query = query.endAt(((Number) endAt).doubleValue(), endAtKey); - } else { - query = query.endAt((String) endAt, endAtKey); - } - } else { - if (endAt instanceof Boolean) { - query = query.endAt((Boolean) endAt); - } else if (endAt instanceof Number) { - query = query.endAt(((Number) endAt).doubleValue()); - } else { - query = query.endAt((String) endAt); - } - } - } - if (parameters.containsKey("equalTo")) { - Object equalTo = parameters.get("equalTo"); - if (parameters.containsKey("equalToKey")) { - String equalToKey = (String) parameters.get("equalToKey"); - if (equalTo instanceof Boolean) { - query = query.equalTo((Boolean) equalTo, equalToKey); - } else if (equalTo instanceof Number) { - query = query.equalTo(((Number) equalTo).doubleValue(), equalToKey); - } else { - query = query.equalTo((String) equalTo, equalToKey); - } - } else { - if (equalTo instanceof Boolean) { - query = query.equalTo((Boolean) equalTo); - } else if (equalTo instanceof Number) { - query = query.equalTo(((Number) equalTo).doubleValue()); - } else { - query = query.equalTo((String) equalTo); - } - } - } - if (parameters.containsKey("limitToFirst")) { - query = query.limitToFirst((int) parameters.get("limitToFirst")); - } - if (parameters.containsKey("limitToLast")) { - query = query.limitToLast((int) parameters.get("limitToLast")); - } - return query; + FirebaseDatabasePlugin plugin = new FirebaseDatabasePlugin(); + plugin.setupMethodChannel(registrar.messenger()); } - private class DefaultCompletionListener implements DatabaseReference.CompletionListener { - private final Result result; - - DefaultCompletionListener(Result result) { - this.result = result; - } - - @Override - public void onComplete(@Nullable DatabaseError error, @NonNull DatabaseReference ref) { - if (error != null) { - result.error(String.valueOf(error.getCode()), error.getMessage(), error.getDetails()); - } else { - result.success(null); - } - } - } - - private class EventObserver implements ChildEventListener, ValueEventListener { - private String requestedEventType; - private int handle; - - EventObserver(String requestedEventType, int handle) { - this.requestedEventType = requestedEventType; - this.handle = handle; - } - - private void sendEvent( - String eventType, @NonNull DataSnapshot snapshot, String previousChildName) { - if (eventType.equals(requestedEventType)) { - Map arguments = new HashMap<>(); - Map snapshotMap = new HashMap<>(); - snapshotMap.put("key", snapshot.getKey()); - snapshotMap.put("value", snapshot.getValue()); - arguments.put("handle", handle); - arguments.put("snapshot", snapshotMap); - arguments.put("previousSiblingKey", previousChildName); - channel.invokeMethod("Event", arguments); - } - } - - @Override - public void onCancelled(@NonNull DatabaseError error) { - Map arguments = new HashMap<>(); - arguments.put("handle", handle); - arguments.put("error", asMap(error)); - channel.invokeMethod("Error", arguments); - } - - @Override - public void onChildAdded(@NonNull DataSnapshot snapshot, String previousChildName) { - sendEvent(EVENT_TYPE_CHILD_ADDED, snapshot, previousChildName); - } - - @Override - public void onChildRemoved(@NonNull DataSnapshot snapshot) { - sendEvent(EVENT_TYPE_CHILD_REMOVED, snapshot, null); - } - - @Override - public void onChildChanged(@NonNull DataSnapshot snapshot, String previousChildName) { - sendEvent(EVENT_TYPE_CHILD_CHANGED, snapshot, previousChildName); - } - - @Override - public void onChildMoved(@NonNull DataSnapshot snapshot, String previousChildName) { - sendEvent(EVENT_TYPE_CHILD_MOVED, snapshot, previousChildName); - } - - @Override - public void onDataChange(@NonNull DataSnapshot snapshot) { - sendEvent(EVENT_TYPE_VALUE, snapshot, null); - } + private void setupMethodChannel(BinaryMessenger messenger) { + channel = + new MethodChannel(messenger, "plugins.flutter.io/firebase_database"); + MethodCallHandlerImpl handler = new MethodCallHandlerImpl(channel); + channel.setMethodCallHandler(handler); } @Override - public void onMethodCall(final MethodCall call, @NonNull final Result result) { - final Map arguments = call.arguments(); - FirebaseDatabase database; - String appName = call.argument("app"); - String databaseURL = call.argument("databaseURL"); - if (appName != null && databaseURL != null) { - database = FirebaseDatabase.getInstance(FirebaseApp.getInstance(appName), databaseURL); - } else if (appName != null) { - database = FirebaseDatabase.getInstance(FirebaseApp.getInstance(appName)); - } else if (databaseURL != null) { - database = FirebaseDatabase.getInstance(databaseURL); - } else { - database = FirebaseDatabase.getInstance(); - } - switch (call.method) { - case "FirebaseDatabase#goOnline": - { - database.goOnline(); - result.success(null); - break; - } - - case "FirebaseDatabase#goOffline": - { - database.goOffline(); - result.success(null); - break; - } - - case "FirebaseDatabase#purgeOutstandingWrites": - { - database.purgeOutstandingWrites(); - result.success(null); - break; - } - - case "FirebaseDatabase#setPersistenceEnabled": - { - Boolean isEnabled = call.argument("enabled"); - try { - database.setPersistenceEnabled(isEnabled); - result.success(true); - } catch (DatabaseException e) { - // Database is already in use, e.g. after hot reload/restart. - result.success(false); - } - break; - } - - case "FirebaseDatabase#setPersistenceCacheSizeBytes": - { - Long cacheSize = call.argument("cacheSize"); - try { - database.setPersistenceCacheSizeBytes(cacheSize); - result.success(true); - } catch (DatabaseException e) { - // Database is already in use, e.g. after hot reload/restart. - result.success(false); - } - break; - } - - case "DatabaseReference#set": - { - Object value = call.argument("value"); - Object priority = call.argument("priority"); - DatabaseReference reference = getReference(database, arguments); - if (priority != null) { - reference.setValue(value, priority, new DefaultCompletionListener(result)); - } else { - reference.setValue(value, new DefaultCompletionListener(result)); - } - break; - } - - case "DatabaseReference#update": - { - Map value = call.argument("value"); - DatabaseReference reference = getReference(database, arguments); - reference.updateChildren(value, new DefaultCompletionListener(result)); - break; - } - - case "DatabaseReference#setPriority": - { - Object priority = call.argument("priority"); - DatabaseReference reference = getReference(database, arguments); - reference.setPriority(priority, new DefaultCompletionListener(result)); - break; - } - - case "DatabaseReference#runTransaction": - { - final DatabaseReference reference = getReference(database, arguments); - - // Initiate native transaction. - reference.runTransaction( - new Transaction.Handler() { - @NonNull - @Override - public Transaction.Result doTransaction(@NonNull MutableData mutableData) { - // Tasks are used to allow native execution of doTransaction to wait while Snapshot is - // processed by logic on the Dart side. - final TaskCompletionSource> updateMutableDataTCS = - new TaskCompletionSource<>(); - final Task> updateMutableDataTCSTask = - updateMutableDataTCS.getTask(); - - final Map doTransactionMap = new HashMap<>(); - doTransactionMap.put("transactionKey", call.argument("transactionKey")); - - final Map snapshotMap = new HashMap<>(); - snapshotMap.put("key", mutableData.getKey()); - snapshotMap.put("value", mutableData.getValue()); - doTransactionMap.put("snapshot", snapshotMap); - - // Return snapshot to Dart side for update. - handler.post( - new Runnable() { - @Override - public void run() { - channel.invokeMethod( - "DoTransaction", - doTransactionMap, - new MethodChannel.Result() { - @Override - @SuppressWarnings("unchecked") - public void success(Object result) { - updateMutableDataTCS.setResult((Map) result); - } - - @Override - public void error( - String errorCode, String errorMessage, Object errorDetails) { - String exceptionMessage = - "Error code: " - + errorCode - + "\nError message: " - + errorMessage - + "\nError details: " - + errorDetails; - updateMutableDataTCS.setException( - new Exception(exceptionMessage)); - } - - @Override - public void notImplemented() { - updateMutableDataTCS.setException( - new Exception("DoTransaction not implemented on Dart side.")); - } - }); - } - }); - - try { - // Wait for updated snapshot from the Dart side. - final Map updatedSnapshotMap = - Tasks.await( - updateMutableDataTCSTask, - (int) arguments.get("transactionTimeout"), - TimeUnit.MILLISECONDS); - // Set value of MutableData to value returned from the Dart side. - mutableData.setValue(updatedSnapshotMap.get("value")); - } catch (ExecutionException | InterruptedException | TimeoutException e) { - Log.e(TAG, "Unable to commit Snapshot update. Transaction failed.", e); - if (e instanceof TimeoutException) { - Log.e(TAG, "Transaction at " + reference.toString() + " timed out."); - } - return Transaction.abort(); - } - return Transaction.success(mutableData); - } - - @Override - public void onComplete( - DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) { - final Map completionMap = new HashMap<>(); - completionMap.put("transactionKey", call.argument("transactionKey")); - if (databaseError != null) { - completionMap.put("error", asMap(databaseError)); - } - completionMap.put("committed", committed); - if (dataSnapshot != null) { - Map snapshotMap = new HashMap<>(); - snapshotMap.put("key", dataSnapshot.getKey()); - snapshotMap.put("value", dataSnapshot.getValue()); - completionMap.put("snapshot", snapshotMap); - } - - // Invoke transaction completion on the Dart side. - handler.post( - new Runnable() { - public void run() { - result.success(completionMap); - } - }); - } - }); - break; - } - - case "OnDisconnect#set": - { - Object value = call.argument("value"); - Object priority = call.argument("priority"); - DatabaseReference reference = getReference(database, arguments); - if (priority != null) { - if (priority instanceof String) { - reference - .onDisconnect() - .setValue(value, (String) priority, new DefaultCompletionListener(result)); - } else if (priority instanceof Double) { - reference - .onDisconnect() - .setValue(value, (double) priority, new DefaultCompletionListener(result)); - } else if (priority instanceof Map) { - reference - .onDisconnect() - .setValue(value, (Map) priority, new DefaultCompletionListener(result)); - } - } else { - reference.onDisconnect().setValue(value, new DefaultCompletionListener(result)); - } - break; - } - - case "OnDisconnect#update": - { - Map value = call.argument("value"); - DatabaseReference reference = getReference(database, arguments); - reference.onDisconnect().updateChildren(value, new DefaultCompletionListener(result)); - break; - } - - case "OnDisconnect#cancel": - { - DatabaseReference reference = getReference(database, arguments); - reference.onDisconnect().cancel(new DefaultCompletionListener(result)); - break; - } - - case "Query#keepSynced": - { - Boolean value = call.argument("value"); - getQuery(database, arguments).keepSynced(value); - result.success(null); - break; - } - - case "Query#observe": - { - String eventType = call.argument("eventType"); - int handle = nextHandle++; - EventObserver observer = new EventObserver(eventType, handle); - observers.put(handle, observer); - if (EVENT_TYPE_VALUE.equals(eventType)) { - getQuery(database, arguments).addValueEventListener(observer); - } else { - getQuery(database, arguments).addChildEventListener(observer); - } - result.success(handle); - break; - } - - case "Query#removeObserver": - { - Query query = getQuery(database, arguments); - Integer handle = call.argument("handle"); - EventObserver observer = observers.get(handle); - if (observer != null) { - if (observer.requestedEventType.equals(EVENT_TYPE_VALUE)) { - query.removeEventListener((ValueEventListener) observer); - } else { - query.removeEventListener((ChildEventListener) observer); - } - observers.delete(handle); - result.success(null); - break; - } else { - result.error("unknown_handle", "removeObserver called on an unknown handle", null); - break; - } - } - - default: - { - result.notImplemented(); - break; - } - } + public void onAttachedToEngine(FlutterPluginBinding binding) { + setupMethodChannel(binding.getFlutterEngine().getDartExecutor()); } - private static Map asMap(DatabaseError error) { - Map map = new HashMap<>(); - map.put("code", error.getCode()); - map.put("message", error.getMessage()); - map.put("details", error.getDetails()); - return map; + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); } } diff --git a/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/MethodCallHandlerImpl.java b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/MethodCallHandlerImpl.java new file mode 100644 index 000000000000..31f5ae9885e4 --- /dev/null +++ b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/MethodCallHandlerImpl.java @@ -0,0 +1,527 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebase.database; + +import android.os.Handler; +import android.util.Log; +import android.util.SparseArray; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; +import com.google.android.gms.tasks.Tasks; +import com.google.firebase.FirebaseApp; +import com.google.firebase.database.ChildEventListener; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseException; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.MutableData; +import com.google.firebase.database.Query; +import com.google.firebase.database.Transaction; +import com.google.firebase.database.ValueEventListener; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { + + private static final String TAG = "MethodCallHandlerImpl"; + + private MethodChannel channel; + + private final Handler handler = new Handler(); + private static final String EVENT_TYPE_CHILD_ADDED = "_EventType.childAdded"; + private static final String EVENT_TYPE_CHILD_REMOVED = "_EventType.childRemoved"; + private static final String EVENT_TYPE_CHILD_CHANGED = "_EventType.childChanged"; + private static final String EVENT_TYPE_CHILD_MOVED = "_EventType.childMoved"; + private static final String EVENT_TYPE_VALUE = "_EventType.value"; + + // Handles are ints used as indexes into the sparse array of active observers + private int nextHandle = 0; + private final SparseArray observers = new SparseArray<>(); + + MethodCallHandlerImpl(MethodChannel channel) { + this.channel = channel; + } + + private DatabaseReference getReference(FirebaseDatabase database, Map arguments) { + String path = (String) arguments.get("path"); + DatabaseReference reference = database.getReference(); + if (path != null) reference = reference.child(path); + return reference; + } + + private Query getQuery(FirebaseDatabase database, Map arguments) { + Query query = getReference(database, arguments); + @SuppressWarnings("unchecked") + Map parameters = (Map) arguments.get("parameters"); + if (parameters == null) return query; + Object orderBy = parameters.get("orderBy"); + if ("child".equals(orderBy)) { + query = query.orderByChild((String) parameters.get("orderByChildKey")); + } else if ("key".equals(orderBy)) { + query = query.orderByKey(); + } else if ("value".equals(orderBy)) { + query = query.orderByValue(); + } else if ("priority".equals(orderBy)) { + query = query.orderByPriority(); + } + if (parameters.containsKey("startAt")) { + Object startAt = parameters.get("startAt"); + if (parameters.containsKey("startAtKey")) { + String startAtKey = (String) parameters.get("startAtKey"); + if (startAt instanceof Boolean) { + query = query.startAt((Boolean) startAt, startAtKey); + } else if (startAt instanceof Number) { + query = query.startAt(((Number) startAt).doubleValue(), startAtKey); + } else { + query = query.startAt((String) startAt, startAtKey); + } + } else { + if (startAt instanceof Boolean) { + query = query.startAt((Boolean) startAt); + } else if (startAt instanceof Number) { + query = query.startAt(((Number) startAt).doubleValue()); + } else { + query = query.startAt((String) startAt); + } + } + } + if (parameters.containsKey("endAt")) { + Object endAt = parameters.get("endAt"); + if (parameters.containsKey("endAtKey")) { + String endAtKey = (String) parameters.get("endAtKey"); + if (endAt instanceof Boolean) { + query = query.endAt((Boolean) endAt, endAtKey); + } else if (endAt instanceof Number) { + query = query.endAt(((Number) endAt).doubleValue(), endAtKey); + } else { + query = query.endAt((String) endAt, endAtKey); + } + } else { + if (endAt instanceof Boolean) { + query = query.endAt((Boolean) endAt); + } else if (endAt instanceof Number) { + query = query.endAt(((Number) endAt).doubleValue()); + } else { + query = query.endAt((String) endAt); + } + } + } + if (parameters.containsKey("equalTo")) { + Object equalTo = parameters.get("equalTo"); + if (parameters.containsKey("equalToKey")) { + String equalToKey = (String) parameters.get("equalToKey"); + if (equalTo instanceof Boolean) { + query = query.equalTo((Boolean) equalTo, equalToKey); + } else if (equalTo instanceof Number) { + query = query.equalTo(((Number) equalTo).doubleValue(), equalToKey); + } else { + query = query.equalTo((String) equalTo, equalToKey); + } + } else { + if (equalTo instanceof Boolean) { + query = query.equalTo((Boolean) equalTo); + } else if (equalTo instanceof Number) { + query = query.equalTo(((Number) equalTo).doubleValue()); + } else { + query = query.equalTo((String) equalTo); + } + } + } + if (parameters.containsKey("limitToFirst")) { + query = query.limitToFirst((int) parameters.get("limitToFirst")); + } + if (parameters.containsKey("limitToLast")) { + query = query.limitToLast((int) parameters.get("limitToLast")); + } + return query; + } + + private class DefaultCompletionListener implements DatabaseReference.CompletionListener { + private final MethodChannel.Result result; + + DefaultCompletionListener(MethodChannel.Result result) { + this.result = result; + } + + @Override + public void onComplete(@Nullable DatabaseError error, @NonNull DatabaseReference ref) { + if (error != null) { + result.error(String.valueOf(error.getCode()), error.getMessage(), error.getDetails()); + } else { + result.success(null); + } + } + } + + private class EventObserver implements ChildEventListener, ValueEventListener { + private String requestedEventType; + private int handle; + + EventObserver(String requestedEventType, int handle) { + this.requestedEventType = requestedEventType; + this.handle = handle; + } + + private void sendEvent( + String eventType, @NonNull DataSnapshot snapshot, String previousChildName) { + if (eventType.equals(requestedEventType)) { + Map arguments = new HashMap<>(); + Map snapshotMap = new HashMap<>(); + snapshotMap.put("key", snapshot.getKey()); + snapshotMap.put("value", snapshot.getValue()); + arguments.put("handle", handle); + arguments.put("snapshot", snapshotMap); + arguments.put("previousSiblingKey", previousChildName); + channel.invokeMethod("Event", arguments); + } + } + + @Override + public void onCancelled(@NonNull DatabaseError error) { + Map arguments = new HashMap<>(); + arguments.put("handle", handle); + arguments.put("error", asMap(error)); + channel.invokeMethod("Error", arguments); + } + + @Override + public void onChildAdded(@NonNull DataSnapshot snapshot, String previousChildName) { + sendEvent(EVENT_TYPE_CHILD_ADDED, snapshot, previousChildName); + } + + @Override + public void onChildRemoved(@NonNull DataSnapshot snapshot) { + sendEvent(EVENT_TYPE_CHILD_REMOVED, snapshot, null); + } + + @Override + public void onChildChanged(@NonNull DataSnapshot snapshot, String previousChildName) { + sendEvent(EVENT_TYPE_CHILD_CHANGED, snapshot, previousChildName); + } + + @Override + public void onChildMoved(@NonNull DataSnapshot snapshot, String previousChildName) { + sendEvent(EVENT_TYPE_CHILD_MOVED, snapshot, previousChildName); + } + + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + sendEvent(EVENT_TYPE_VALUE, snapshot, null); + } + } + + @Override + public void onMethodCall(final MethodCall call, @NonNull final MethodChannel.Result result) { + final Map arguments = call.arguments(); + FirebaseDatabase database; + String appName = call.argument("app"); + String databaseURL = call.argument("databaseURL"); + if (appName != null && databaseURL != null) { + database = FirebaseDatabase.getInstance(FirebaseApp.getInstance(appName), databaseURL); + } else if (appName != null) { + database = FirebaseDatabase.getInstance(FirebaseApp.getInstance(appName)); + } else if (databaseURL != null) { + database = FirebaseDatabase.getInstance(databaseURL); + } else { + database = FirebaseDatabase.getInstance(); + } + switch (call.method) { + case "FirebaseDatabase#goOnline": + { + database.goOnline(); + result.success(null); + break; + } + + case "FirebaseDatabase#goOffline": + { + database.goOffline(); + result.success(null); + break; + } + + case "FirebaseDatabase#purgeOutstandingWrites": + { + database.purgeOutstandingWrites(); + result.success(null); + break; + } + + case "FirebaseDatabase#setPersistenceEnabled": + { + Boolean isEnabled = call.argument("enabled"); + try { + database.setPersistenceEnabled(isEnabled); + result.success(true); + } catch (DatabaseException e) { + // Database is already in use, e.g. after hot reload/restart. + result.success(false); + } + break; + } + + case "FirebaseDatabase#setPersistenceCacheSizeBytes": + { + Long cacheSize = call.argument("cacheSize"); + try { + database.setPersistenceCacheSizeBytes(cacheSize); + result.success(true); + } catch (DatabaseException e) { + // Database is already in use, e.g. after hot reload/restart. + result.success(false); + } + break; + } + + case "DatabaseReference#set": + { + Object value = call.argument("value"); + Object priority = call.argument("priority"); + DatabaseReference reference = getReference(database, arguments); + if (priority != null) { + reference.setValue(value, priority, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } else { + reference.setValue(value, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } + break; + } + + case "DatabaseReference#update": + { + Map value = call.argument("value"); + DatabaseReference reference = getReference(database, arguments); + reference.updateChildren(value, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + break; + } + + case "DatabaseReference#setPriority": + { + Object priority = call.argument("priority"); + DatabaseReference reference = getReference(database, arguments); + reference.setPriority(priority, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + break; + } + + case "DatabaseReference#runTransaction": + { + final DatabaseReference reference = getReference(database, arguments); + + // Initiate native transaction. + reference.runTransaction( + new Transaction.Handler() { + @NonNull + @Override + public Transaction.Result doTransaction(@NonNull MutableData mutableData) { + // Tasks are used to allow native execution of doTransaction to wait while Snapshot is + // processed by logic on the Dart side. + final TaskCompletionSource> updateMutableDataTCS = + new TaskCompletionSource<>(); + final Task> updateMutableDataTCSTask = + updateMutableDataTCS.getTask(); + + final Map doTransactionMap = new HashMap<>(); + doTransactionMap.put("transactionKey", call.argument("transactionKey")); + + final Map snapshotMap = new HashMap<>(); + snapshotMap.put("key", mutableData.getKey()); + snapshotMap.put("value", mutableData.getValue()); + doTransactionMap.put("snapshot", snapshotMap); + + // Return snapshot to Dart side for update. + handler.post( + new Runnable() { + @Override + public void run() { + channel.invokeMethod( + "DoTransaction", + doTransactionMap, + new MethodChannel.Result() { + @Override + @SuppressWarnings("unchecked") + public void success(Object result) { + updateMutableDataTCS.setResult((Map) result); + } + + @Override + public void error( + String errorCode, String errorMessage, Object errorDetails) { + String exceptionMessage = + "Error code: " + + errorCode + + "\nError message: " + + errorMessage + + "\nError details: " + + errorDetails; + updateMutableDataTCS.setException( + new Exception(exceptionMessage)); + } + + @Override + public void notImplemented() { + updateMutableDataTCS.setException( + new Exception("DoTransaction not implemented on Dart side.")); + } + }); + } + }); + + try { + // Wait for updated snapshot from the Dart side. + final Map updatedSnapshotMap = + Tasks.await( + updateMutableDataTCSTask, + (int) arguments.get("transactionTimeout"), + TimeUnit.MILLISECONDS); + // Set value of MutableData to value returned from the Dart side. + mutableData.setValue(updatedSnapshotMap.get("value")); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + Log.e(TAG, "Unable to commit Snapshot update. Transaction failed.", e); + if (e instanceof TimeoutException) { + Log.e(TAG, "Transaction at " + reference.toString() + " timed out."); + } + return Transaction.abort(); + } + return Transaction.success(mutableData); + } + + @Override + public void onComplete( + DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) { + final Map completionMap = new HashMap<>(); + completionMap.put("transactionKey", call.argument("transactionKey")); + if (databaseError != null) { + completionMap.put("error", asMap(databaseError)); + } + completionMap.put("committed", committed); + if (dataSnapshot != null) { + Map snapshotMap = new HashMap<>(); + snapshotMap.put("key", dataSnapshot.getKey()); + snapshotMap.put("value", dataSnapshot.getValue()); + completionMap.put("snapshot", snapshotMap); + } + + // Invoke transaction completion on the Dart side. + handler.post( + new Runnable() { + public void run() { + result.success(completionMap); + } + }); + } + }); + break; + } + + case "OnDisconnect#set": + { + Object value = call.argument("value"); + Object priority = call.argument("priority"); + DatabaseReference reference = getReference(database, arguments); + if (priority != null) { + if (priority instanceof String) { + reference + .onDisconnect() + .setValue(value, (String) priority, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } else if (priority instanceof Double) { + reference + .onDisconnect() + .setValue(value, (double) priority, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } else if (priority instanceof Map) { + reference + .onDisconnect() + .setValue(value, (Map) priority, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } + } else { + reference.onDisconnect().setValue(value, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + } + break; + } + + case "OnDisconnect#update": + { + Map value = call.argument("value"); + DatabaseReference reference = getReference(database, arguments); + reference.onDisconnect().updateChildren(value, new MethodCallHandlerImpl.DefaultCompletionListener(result)); + break; + } + + case "OnDisconnect#cancel": + { + DatabaseReference reference = getReference(database, arguments); + reference.onDisconnect().cancel(new MethodCallHandlerImpl.DefaultCompletionListener(result)); + break; + } + + case "Query#keepSynced": + { + Boolean value = call.argument("value"); + getQuery(database, arguments).keepSynced(value); + result.success(null); + break; + } + + case "Query#observe": + { + String eventType = call.argument("eventType"); + int handle = nextHandle++; + MethodCallHandlerImpl.EventObserver observer = new MethodCallHandlerImpl.EventObserver(eventType, handle); + observers.put(handle, observer); + if (EVENT_TYPE_VALUE.equals(eventType)) { + getQuery(database, arguments).addValueEventListener(observer); + } else { + getQuery(database, arguments).addChildEventListener(observer); + } + result.success(handle); + break; + } + + case "Query#removeObserver": + { + Query query = getQuery(database, arguments); + Integer handle = call.argument("handle"); + MethodCallHandlerImpl.EventObserver observer = observers.get(handle); + if (observer != null) { + if (observer.requestedEventType.equals(EVENT_TYPE_VALUE)) { + query.removeEventListener((ValueEventListener) observer); + } else { + query.removeEventListener((ChildEventListener) observer); + } + observers.delete(handle); + result.success(null); + break; + } else { + result.error("unknown_handle", "removeObserver called on an unknown handle", null); + break; + } + } + + default: + { + result.notImplemented(); + break; + } + } + } + + private static Map asMap(DatabaseError error) { + Map map = new HashMap<>(); + map.put("code", error.getCode()); + map.put("message", error.getMessage()); + map.put("details", error.getDetails()); + return map; + } +} diff --git a/packages/firebase_database/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_database/example/android/app/src/main/AndroidManifest.xml index 794bfa20d51d..f7805c70e182 100755 --- a/packages/firebase_database/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_database/example/android/app/src/main/AndroidManifest.xml @@ -4,12 +4,20 @@ - + + diff --git a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/EmbeddingV1Activity.java b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/EmbeddingV1Activity.java new file mode 100644 index 000000000000..b241c4c08872 --- /dev/null +++ b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/EmbeddingV1Activity.java @@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebasedatabaseexample; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class EmbeddingV1Activity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java index 0c58e26a5c1b..7d466a39567e 100644 --- a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java +++ b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java @@ -4,14 +4,21 @@ package io.flutter.plugins.firebasedatabaseexample; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.embedding.android.FlutterActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; +import io.flutter.plugins.firebase.core.FirebaseCorePlugin; +import io.flutter.plugins.firebase.database.FirebaseDatabasePlugin; public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } + + @Override + public void configureFlutterEngine(FlutterEngine flutterEngine) { + super.configureFlutterEngine(flutterEngine); + flutterEngine.getPlugins().add(new FirebaseDatabasePlugin()); + + ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine); + FirebaseCorePlugin.registerWith( + shimPluginRegistry.registrarFor("io.flutter.plugins.firebase.core.FirebaseCorePlugin")); + } } diff --git a/packages/firebase_database/example/android/gradle.properties b/packages/firebase_database/example/android/gradle.properties index 8bd86f680510..7be3d8b46841 100755 --- a/packages/firebase_database/example/android/gradle.properties +++ b/packages/firebase_database/example/android/gradle.properties @@ -1 +1,2 @@ org.gradle.jvmargs=-Xmx1536M +android.enableR8=true diff --git a/packages/firebase_database/example/lib/main.dart b/packages/firebase_database/example/lib/main.dart index c22374aa3e94..d2753c9e8b45 100755 --- a/packages/firebase_database/example/lib/main.dart +++ b/packages/firebase_database/example/lib/main.dart @@ -11,6 +11,7 @@ import 'package:firebase_database/firebase_database.dart'; import 'package:firebase_database/ui/firebase_animated_list.dart'; Future main() async { + WidgetsFlutterBinding.ensureInitialized(); final FirebaseApp app = await FirebaseApp.configure( name: 'db2', options: Platform.isIOS From 8351a45e6c01c7867700c7de381bfbef48235b5b Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 8 Oct 2019 16:15:19 -0700 Subject: [PATCH 06/11] unable androidX --- packages/firebase_database/example/android/gradle.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/firebase_database/example/android/gradle.properties b/packages/firebase_database/example/android/gradle.properties index 7be3d8b46841..511e820fd401 100755 --- a/packages/firebase_database/example/android/gradle.properties +++ b/packages/firebase_database/example/android/gradle.properties @@ -1,2 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true +seAndroidX=true +android.enableJetifier=true From 5cec507e7b2256af38a7654276befe5c9cbc4762 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 9 Oct 2019 11:46:42 -0700 Subject: [PATCH 07/11] revert --- .../FirebaseRemoteConfigPlugin.java | 190 ++++++++++++++++-- .../MethodCallHandlerImpl.java | 181 ----------------- .../android/app/src/main/AndroidManifest.xml | 11 +- .../EmbeddingV1Activity.java | 13 -- .../MainActivity.java | 19 +- .../example/android/gradle.properties | 3 - .../example/lib/main.dart | 1 - 7 files changed, 178 insertions(+), 240 deletions(-) delete mode 100644 packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java delete mode 100644 packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java index 2db9b16bb827..d07a9ad1d57a 100644 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java +++ b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/FirebaseRemoteConfigPlugin.java @@ -5,40 +5,192 @@ package io.flutter.plugins.firebase.firebaseremoteconfig; import android.content.Context; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.remoteconfig.FirebaseRemoteConfig; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; +import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; +import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** FirebaseRemoteConfigPlugin */ -public class FirebaseRemoteConfigPlugin implements FlutterPlugin { +public class FirebaseRemoteConfigPlugin implements MethodCallHandler { - static final String TAG = "FirebaseRemoteConfigPlugin"; - static final String PREFS_NAME = + public static final String TAG = "FirebaseRemoteConfigPlugin"; + public static final String PREFS_NAME = "io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin"; - static final String METHOD_CHANNEL = "plugins.flutter.io/firebase_remote_config"; + public static final String DEFAULT_PREF_KEY = "default_keys"; - private MethodChannel channel; + private static SharedPreferences sharedPreferences; public static void registerWith(Registrar registrar) { - FirebaseRemoteConfigPlugin plugin = new FirebaseRemoteConfigPlugin(); - plugin.setupChannel(registrar.messenger(), registrar.context()); + final MethodChannel channel = + new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_remote_config"); + channel.setMethodCallHandler(new FirebaseRemoteConfigPlugin()); + sharedPreferences = registrar.context().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); } @Override - public void onAttachedToEngine(FlutterPluginBinding binding) { - setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext()); + public void onMethodCall(MethodCall call, final Result result) { + switch (call.method) { + case "RemoteConfig#instance": + { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + FirebaseRemoteConfig.getInstance().getInfo(); + + Map properties = new HashMap<>(); + properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + properties.put( + "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); + properties.put("parameters", getConfigParameters()); + result.success(properties); + break; + } + case "RemoteConfig#setConfigSettings": + { + boolean debugMode = call.argument("debugMode"); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + FirebaseRemoteConfigSettings settings = + new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); + firebaseRemoteConfig.setConfigSettings(settings); + result.success(null); + break; + } + case "RemoteConfig#fetch": + { + long expiration = ((Number) call.argument("expiration")).longValue(); + final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + firebaseRemoteConfig + .fetch(expiration) + .addOnCompleteListener( + new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = + firebaseRemoteConfig.getInfo(); + Map properties = new HashMap<>(); + properties.put( + "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); + properties.put( + "lastFetchStatus", + mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); + if (!task.isSuccessful()) { + final Exception exception = task.getException(); + + if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { + properties.put( + "fetchThrottledEnd", + ((FirebaseRemoteConfigFetchThrottledException) exception) + .getThrottleEndTimeMillis()); + String errorMessage = + "Fetch has been throttled. See the error's " + + "FETCH_THROTTLED_END field for throttle end time."; + result.error("fetchFailedThrottled", errorMessage, properties); + } else { + String errorMessage = + "Unable to complete fetch. Reason is unknown " + + "but this could be due to lack of connectivity."; + result.error("fetchFailed", errorMessage, properties); + } + } else { + result.success(properties); + } + } + }); + break; + } + case "RemoteConfig#activate": + { + boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); + Map properties = new HashMap<>(); + properties.put("parameters", getConfigParameters()); + properties.put("newConfig", newConfig); + result.success(properties); + break; + } + case "RemoteConfig#setDefaults": + { + Map defaults = call.argument("defaults"); + FirebaseRemoteConfig.getInstance().setDefaults(defaults); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); + result.success(null); + break; + } + default: + { + result.notImplemented(); + break; + } + } } - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) { - channel = null; + private Map getConfigParameters() { + FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); + Map parameterMap = new HashMap<>(); + Set keys = firebaseRemoteConfig.getKeysByPrefix(""); + for (String key : keys) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); + parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); + } + // Add default parameters if missing since `getKeysByPrefix` does not return default keys. + Set defaultKeys = + sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); + for (String defaultKey : defaultKeys) { + if (!parameterMap.containsKey(defaultKey)) { + FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); + parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); + } + } + return parameterMap; + } + + private Map createRemoteConfigValueMap( + FirebaseRemoteConfigValue remoteConfigValue) { + Map valueMap = new HashMap<>(); + valueMap.put("value", remoteConfigValue.asByteArray()); + valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); + return valueMap; + } + + private String mapLastFetchStatus(int status) { + switch (status) { + case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: + return "success"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: + return "failure"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: + return "throttled"; + case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: + return "noFetchYet"; + default: + return "failure"; + } } - private void setupChannel(BinaryMessenger messenger, Context context) { - MethodCallHandlerImpl handler = - new MethodCallHandlerImpl(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)); - channel = new MethodChannel(messenger, METHOD_CHANNEL); - channel.setMethodCallHandler(handler); + private String mapValueSource(int source) { + switch (source) { + case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: + return "static"; + case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: + return "default"; + case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: + return "remote"; + default: + return "static"; + } } } diff --git a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java b/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java deleted file mode 100644 index 5c59bad7f116..000000000000 --- a/packages/firebase_remote_config/android/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfig/MethodCallHandlerImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -package io.flutter.plugins.firebase.firebaseremoteconfig; - -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.remoteconfig.FirebaseRemoteConfig; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler { - - private static final String DEFAULT_PREF_KEY = "default_keys"; - - private static SharedPreferences sharedPreferences; - - MethodCallHandlerImpl(@NonNull SharedPreferences sharedPreferences) { - this.sharedPreferences = sharedPreferences; - } - - @Override - public void onMethodCall(MethodCall call, final MethodChannel.Result result) { - switch (call.method) { - case "RemoteConfig#instance": - { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - FirebaseRemoteConfig.getInstance().getInfo(); - - Map properties = new HashMap<>(); - properties.put("lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - properties.put( - "inDebugMode", firebaseRemoteConfigInfo.getConfigSettings().isDeveloperModeEnabled()); - properties.put("parameters", getConfigParameters()); - result.success(properties); - break; - } - case "RemoteConfig#setConfigSettings": - { - boolean debugMode = call.argument("debugMode"); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - FirebaseRemoteConfigSettings settings = - new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(debugMode).build(); - firebaseRemoteConfig.setConfigSettings(settings); - result.success(null); - break; - } - case "RemoteConfig#fetch": - { - long expiration = ((Number) call.argument("expiration")).longValue(); - final FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - firebaseRemoteConfig - .fetch(expiration) - .addOnCompleteListener( - new OnCompleteListener() { - @Override - public void onComplete(@NonNull Task task) { - FirebaseRemoteConfigInfo firebaseRemoteConfigInfo = - firebaseRemoteConfig.getInfo(); - Map properties = new HashMap<>(); - properties.put( - "lastFetchTime", firebaseRemoteConfigInfo.getFetchTimeMillis()); - properties.put( - "lastFetchStatus", - mapLastFetchStatus(firebaseRemoteConfigInfo.getLastFetchStatus())); - if (!task.isSuccessful()) { - final Exception exception = task.getException(); - - if (exception instanceof FirebaseRemoteConfigFetchThrottledException) { - properties.put( - "fetchThrottledEnd", - ((FirebaseRemoteConfigFetchThrottledException) exception) - .getThrottleEndTimeMillis()); - String errorMessage = - "Fetch has been throttled. See the error's " - + "FETCH_THROTTLED_END field for throttle end time."; - result.error("fetchFailedThrottled", errorMessage, properties); - } else { - String errorMessage = - "Unable to complete fetch. Reason is unknown " - + "but this could be due to lack of connectivity."; - result.error("fetchFailed", errorMessage, properties); - } - } else { - result.success(properties); - } - } - }); - break; - } - case "RemoteConfig#activate": - { - boolean newConfig = FirebaseRemoteConfig.getInstance().activateFetched(); - Map properties = new HashMap<>(); - properties.put("parameters", getConfigParameters()); - properties.put("newConfig", newConfig); - result.success(properties); - break; - } - case "RemoteConfig#setDefaults": - { - Map defaults = call.argument("defaults"); - FirebaseRemoteConfig.getInstance().setDefaults(defaults); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putStringSet(DEFAULT_PREF_KEY, defaults.keySet()).apply(); - result.success(null); - break; - } - default: - { - result.notImplemented(); - break; - } - } - } - - private Map getConfigParameters() { - FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); - Map parameterMap = new HashMap<>(); - Set keys = firebaseRemoteConfig.getKeysByPrefix(""); - for (String key : keys) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(key); - parameterMap.put(key, createRemoteConfigValueMap(remoteConfigValue)); - } - // Add default parameters if missing since `getKeysByPrefix` does not return default keys. - Set defaultKeys = - sharedPreferences.getStringSet(DEFAULT_PREF_KEY, new HashSet()); - for (String defaultKey : defaultKeys) { - if (!parameterMap.containsKey(defaultKey)) { - FirebaseRemoteConfigValue remoteConfigValue = firebaseRemoteConfig.getValue(defaultKey); - parameterMap.put(defaultKey, createRemoteConfigValueMap(remoteConfigValue)); - } - } - return parameterMap; - } - - private Map createRemoteConfigValueMap( - FirebaseRemoteConfigValue remoteConfigValue) { - Map valueMap = new HashMap<>(); - valueMap.put("value", remoteConfigValue.asByteArray()); - valueMap.put("source", mapValueSource(remoteConfigValue.getSource())); - return valueMap; - } - - private String mapLastFetchStatus(int status) { - switch (status) { - case FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS: - return "success"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_FAILURE: - return "failure"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED: - return "throttled"; - case FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET: - return "noFetchYet"; - default: - return "failure"; - } - } - - private String mapValueSource(int source) { - switch (source) { - case FirebaseRemoteConfig.VALUE_SOURCE_STATIC: - return "static"; - case FirebaseRemoteConfig.VALUE_SOURCE_DEFAULT: - return "default"; - case FirebaseRemoteConfig.VALUE_SOURCE_REMOTE: - return "remote"; - default: - return "static"; - } - } -} diff --git a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml index 7100b12a4e6e..fe4292fe0322 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_remote_config/example/android/app/src/main/AndroidManifest.xml @@ -17,9 +17,8 @@ android:label="firebase_remote_config_example" android:icon="@mipmap/ic_launcher"> - - diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java deleted file mode 100644 index 2af625cab23d..000000000000 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/EmbeddingV1Activity.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.flutter.plugins.firebase.firebaseremoteconfigexample; - -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; - -public class EmbeddingV1Activity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} diff --git a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java index 078bb260ecf4..ef048c74f4df 100644 --- a/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java +++ b/packages/firebase_remote_config/example/android/app/src/main/java/io/flutter/plugins/firebase/firebaseremoteconfigexample/MainActivity.java @@ -1,20 +1,13 @@ package io.flutter.plugins.firebase.firebaseremoteconfigexample; -import io.flutter.embedding.android.FlutterActivity; -import io.flutter.embedding.engine.FlutterEngine; -import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry; -import io.flutter.plugins.firebase.core.FirebaseCorePlugin; -import io.flutter.plugins.firebase.firebaseremoteconfig.FirebaseRemoteConfigPlugin; +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { - @Override - public void configureFlutterEngine(FlutterEngine flutterEngine) { - super.configureFlutterEngine(flutterEngine); - flutterEngine.getPlugins().add(new FirebaseRemoteConfigPlugin()); - - ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine); - FirebaseCorePlugin.registerWith( - shimPluginRegistry.registrarFor("io.flutter.plugins.firebase.core.FirebaseCorePlugin")); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); } } diff --git a/packages/firebase_remote_config/example/android/gradle.properties b/packages/firebase_remote_config/example/android/gradle.properties index a5965ab8dced..8bd86f680510 100644 --- a/packages/firebase_remote_config/example/android/gradle.properties +++ b/packages/firebase_remote_config/example/android/gradle.properties @@ -1,4 +1 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file diff --git a/packages/firebase_remote_config/example/lib/main.dart b/packages/firebase_remote_config/example/lib/main.dart index 89a7d6de387e..8db737372086 100644 --- a/packages/firebase_remote_config/example/lib/main.dart +++ b/packages/firebase_remote_config/example/lib/main.dart @@ -8,7 +8,6 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/material.dart'; void main() { - WidgetsFlutterBinding.ensureInitialized(); runApp(MaterialApp( title: 'Remote Config Example', home: FutureBuilder( From 38d96fe66763a677237e8e235d4656eec836b567 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 11 Oct 2019 14:11:59 -0700 Subject: [PATCH 08/11] fix gradle --- .../firebase_database/android/build.gradle | 24 +++++++++++++++++++ .../example/android/gradle.properties | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/firebase_database/android/build.gradle b/packages/firebase_database/android/build.gradle index 484c0976d1e3..e04062ede776 100755 --- a/packages/firebase_database/android/build.gradle +++ b/packages/firebase_database/android/build.gradle @@ -51,3 +51,27 @@ android { } apply from: file("./user-agent.gradle") + +afterEvaluate { + def containsEmbeddingDependencies = false + for (def configuration : configurations.all) { + for (def dependency : configuration.dependencies) { + if (dependency.group == 'io.flutter' && + dependency.name.startsWith('flutter_embedding') && + dependency.isTransitive()) + { + containsEmbeddingDependencies = true + break + } + } + } + if (!containsEmbeddingDependencies) { + android { + dependencies { + def lifecycle_version = "2.1.0" + api "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" + api "androidx.lifecycle:lifecycle-runtime:$lifecycle_version" + } + } + } +} diff --git a/packages/firebase_database/example/android/gradle.properties b/packages/firebase_database/example/android/gradle.properties index 511e820fd401..38c8d4544ff1 100755 --- a/packages/firebase_database/example/android/gradle.properties +++ b/packages/firebase_database/example/android/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true -seAndroidX=true +android.useAndroidX=true android.enableJetifier=true From a852c60fc6a9250bdf23670c89cbda17a2f70871 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 15 Oct 2019 16:11:51 -0700 Subject: [PATCH 09/11] Update MainActivity.java --- .../flutter/plugins/firebasedatabaseexample/MainActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java index 7d466a39567e..08a84ee8a7ed 100644 --- a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java +++ b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java @@ -12,6 +12,8 @@ public class MainActivity extends FlutterActivity { + // TODO(cyanglaz): Remove this once v2 of GeneratedPluginRegistrant rolls to stable. + // https://github.com/flutter/flutter/issues/42694 @Override public void configureFlutterEngine(FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); From 3fa430702c52ca4b07203bfc8d5be222e2ae5f42 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 13 Nov 2019 20:00:12 -0800 Subject: [PATCH 10/11] update firebase core dependency --- .../plugins/firebase/database/FirebaseDatabasePlugin.java | 1 - .../flutter/plugins/firebasedatabaseexample/MainActivity.java | 4 ++-- packages/firebase_database/example/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java index de344c6888ef..e007f932e725 100644 --- a/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java +++ b/packages/firebase_database/android/src/main/java/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.java @@ -4,7 +4,6 @@ package io.flutter.plugins.firebase.database; - import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodChannel; diff --git a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java index f0c047b78d32..b52b4395eefc 100644 --- a/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java +++ b/packages/firebase_database/example/android/app/src/main/java/io/flutter/plugins/firebasedatabaseexample/MainActivity.java @@ -4,9 +4,9 @@ package io.flutter.plugins.firebasedatabaseexample; -import dev.flutter.plugins.e2e.E2EPlugin; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.firebase.core.FirebaseCorePlugin; import io.flutter.plugins.firebase.database.FirebaseDatabasePlugin; public class MainActivity extends FlutterActivity { @@ -17,6 +17,6 @@ public class MainActivity extends FlutterActivity { public void configureFlutterEngine(FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); flutterEngine.getPlugins().add(new FirebaseDatabasePlugin()); - flutterEngine.getPlugins().add(new E2EPlugin()); + flutterEngine.getPlugins().add(new FirebaseCorePlugin()); } } diff --git a/packages/firebase_database/example/pubspec.yaml b/packages/firebase_database/example/pubspec.yaml index 193309eabb07..de0c16a7dc74 100755 --- a/packages/firebase_database/example/pubspec.yaml +++ b/packages/firebase_database/example/pubspec.yaml @@ -6,7 +6,7 @@ dependencies: sdk: flutter firebase_database: path: ../ - firebase_core: ^0.4.0 + firebase_core: ^0.4.1 dev_dependencies: flutter_driver: From 88bd5dc168ab2c7ba71e5d1c113df3f5cc0b3f78 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 13 Nov 2019 20:18:17 -0800 Subject: [PATCH 11/11] fix analyze error --- .../example/test_driver/firebase_database_e2e.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/firebase_database/example/test_driver/firebase_database_e2e.dart b/packages/firebase_database/example/test_driver/firebase_database_e2e.dart index 5f8e54308ae8..3b11659bdd2d 100644 --- a/packages/firebase_database/example/test_driver/firebase_database_e2e.dart +++ b/packages/firebase_database/example/test_driver/firebase_database_e2e.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'package:e2e/e2e.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:firebase_database/firebase_database.dart';