When initilising remote config this error is thrown.
remoteConfig = await RemoteConfig.instance;
remoteConfig.setConfigSettings(RemoteConfigSettings(debugMode: true));
await remoteConfig.fetch(expiration: const Duration(seconds: 1));
await remoteConfig.activateFetched();
String stingified = remoteConfig.getString("app_questions");
Bad state: Future already completed
✓] Flutter (Channel stable, v1.9.1+hotfix.2, on Mac OS X 10.14.6 18G95, locale en-GB)
• Flutter version 1.9.1+hotfix.2 at /Users/earyzhe/dev/SDKs/flutter
• Framework revision 2d2a1ffec9 (2 weeks ago), 2019-09-06 18:39:49 -0700
• Engine revision b863200c37
• Dart version 2.5.0
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/earyzhe/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 11.0)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.0, Build version 11A420a
• CocoaPods version 1.7.5
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 39.0.3
• Dart plugin version 191.8423
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] IntelliJ IDEA Community Edition (version 2018.3.4)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
• Flutter plugin version 33.2.2
• Dart plugin version 183.5901
[✓] VS Code (version 1.38.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.4.1
[✓] Connected device (3 available)
• Android SDK built for x86 • emulator-5556 • android-x86 • Android 9 (API 28) (emulator)
• Andrew's iPhone • 6aa0c9719a85c174869a09656237b42f23701a91 • ios • iOS 13.0
• iPhone 11 Pro Max • F7FDFDAF-B8D3-478B-AF97-927C3237EB43 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-0 (simulator)
• No issues found!
I reported this issue a while ago and opened a pull request to fix this issue. flutter/flutter#38060
@earyzhe Is it possible that due to state changes in Flutter the code you sent gets executed twice shortly after each other? Or you call RemoteConfig.instance somewhere else at the same time?
This is what happened to me.
@kroikie @collinjackson There is a test to check for this use case: doubleInstance
What I've done:
flutterfirefirebase_remote_config-v0.3.0+1cd packages/firebase_remote_configflutter pub getflutter test --plain-name doubleInstance test/firebase_remote_config_test.dart
Test result
> flutter test --plain-name doubleInstance test/firebase_remote_config_test.dart
00:03 +0 -1: RemoteConfig doubleInstance [E]
Bad state: Future already completed
dart:async _AsyncCompleter.complete
package:firebase_remote_config/src/remote_config.dart 36:26 RemoteConfig.instance
===== asynchronous gap ===========================
dart:async Future.wait
test/firebase_remote_config_test.dart 62:14 main.<fn>.<fn>
dart:async _AsyncAwaitCompleter.start
test/firebase_remote_config_test.dart 57:28 main.<fn>.<fn>
00:03 +0 -1: Some tests failed.
Interestingly, if I run all tests using: flutter test test/firebase_remote_config_test.dart everything works as expected.
From my understanding of the code, this can be explained like this:
RemoteConfig.instance._instanceCompleter is now complete_instanceCompleter property is static the state is preserved across tests and still is completed when...RemoteConfig.instance gets called twice the both won't go into this line which causes the error as the _instanceCompleter is already completed from the previous test.StateError which occurs if the first two calls to RemoteConfig.instance happen at the same time.From that, I went to make the tests independent from each other:
First I made _instanceCompleter visible for testing like this:
@visibleForTesting
static Completer<RemoteConfig> instanceCompleter = Completer<RemoteConfig>();
And added a teardown call to reset the instanceCompleter to the default value:
tearDown(() {
RemoteConfig.instanceCompleter = Completer<RemoteConfig>();
});
Now the doubleInstance test fails as expected.
To fix the error itself, I added used try/catch around the instanceCompleter.complete() call and only ignore StateErrors with the message Future already completed.
I hope this is an acceptable solution to this problem.
I opened up a pull request to fix this bug and make the test behave as expected. #2061
I'm having this issue outside test environment.
await RemoteConfig.instance is throwing Bad State: Future already completed always.
My code snippet:
remoteConfig = await RemoteConfig.instance;
await remoteConfig.fetch(expiration: const Duration(hours: 0));
await remoteConfig.activateFetched();
My workaround was just to add try+catch and keep the flow going when the error is BadState: Future already completed
flutter doctor -v :
[✓] Flutter (Channel stable, v1.17.5, on Linux, locale pt_BR.UTF-8)
• Flutter version 1.17.5 at /home/leonardo/Documentos/devTools/flutter
• Framework revision 8af6b2f038 (5 weeks ago), 2020-06-30 12:53:55 -0700
• Engine revision ee76268252
• Dart version 2.8.4
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /home/leonardo/Android/Sdk
• Platform android-29, build-tools 29.0.3
• Java binary at: /opt/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
• All Android licenses accepted.
[✓] Android Studio (version 4.0)
• Android Studio at /opt/android-studio
• Flutter plugin version 47.1.2
• Dart plugin version 193.7361
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
[✓] Connected device (1 available)
• moto g 7 play • 0056621193 • android-arm • Android 10 (API 29)
Most helpful comment
@earyzhe Is it possible that due to state changes in Flutter the code you sent gets executed twice shortly after each other? Or you call
RemoteConfig.instancesomewhere else at the same time?This is what happened to me.
@kroikie @collinjackson There is a test to check for this use case: doubleInstance
What I've done:
flutterfirefirebase_remote_config-v0.3.0+1cd packages/firebase_remote_configflutter pub getflutter test --plain-name doubleInstance test/firebase_remote_config_test.dartTest result
Interestingly, if I run all tests using:
flutter test test/firebase_remote_config_test.darteverything works as expected.From my understanding of the code, this can be explained like this:
1.1. Test calls
RemoteConfig.instance.1.2. By calling [1.1] the
_instanceCompleteris now complete1.3. Because the
_instanceCompleterproperty is static the state is preserved across tests and still is completed when...2.1. When
RemoteConfig.instancegets called twice the both won't go into this line which causes the error as the_instanceCompleteris already completed from the previous test.2.2. None of the calls throw the
StateErrorwhich occurs if the first two calls toRemoteConfig.instancehappen at the same time.From that, I went to make the tests independent from each other:
First I made
_instanceCompletervisible for testing like this:And added a teardown call to reset the
instanceCompleterto the default value:Now the
doubleInstancetest fails as expected.To fix the error itself, I added used try/catch around the
instanceCompleter.complete()call and only ignoreStateErrors with the messageFuture already completed.I hope this is an acceptable solution to this problem.
I opened up a pull request to fix this bug and make the test behave as expected. #2061