Skip to content

Bad state: Future already completed #195

Description

@anjrew

When initilising remote config this error is thrown.

The code

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");

The Error

Bad state: Future already completed

Output Flutter -v:

✓] 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!

Activity

  1. IchordeDionysos commented on Feb 26, 2020

    @IchordeDionysos
    Contributor

    I reported this issue a while ago and opened a pull request to fix this issue. flutter/flutter#38060

  2. IchordeDionysos commented on Feb 26, 2020

    @IchordeDionysos
    Contributor

    @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:

    1. Clone flutterfire
    2. Checkout firebase_remote_config-v0.3.0+1
    3. Run cd packages/firebase_remote_config
    4. Run flutter pub get
    5. Run test flutter test --plain-name doubleInstance test/firebase_remote_config_test.dart
    6. See test fail with error:
    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:

    1. Test instance starts to run to checks if the instance can be created.
      1.1. Test calls RemoteConfig.instance.
      1.2. By calling [1.1] the _instanceCompleter is now complete
      1.3. Because the _instanceCompleter property is static the state is preserved across tests and still is completed when...
    2. Test doubleInstance starts
      2.1. 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.
      2.2. None of the calls throw the 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

  3. leonardoschluter commented on Aug 6, 2020

    @leonardoschluter

    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)

  4. IchordeDionysos commented on Dec 29, 2020

    @IchordeDionysos
    Contributor

    This issue seems to being fixed soon, due to a fundamental rework of the Remote Config plugin (#4186) by @kroikie 😍
    PR is now ready for review 👍

    Will test if it actually fixes the issue, but as the underlying code responsible for this bug was replaced with a completely rewritten synchronous (rather than asynchronous) implementation it would be unlogical if it didn't 😂

  5. IchordeDionysos commented on Jan 17, 2021

    @IchordeDionysos
    Contributor

    @earyzhe there is now a pre-release version available for Remote Config which should solve this issue:
    https://pub.dev/packages/firebase_remote_config/versions#prerelease

    So I think this issue could be closed now :)

  6. locked and limited conversation to collaborators on Apr 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    impact: customerA bug with low impact (e.g. affecting only a few customers or has a workaround). (P3)plugin: remote_configtype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions