7

I have a Flutter application that uses Firebase as its back-end. I use Firebase emulators to test my app in debug mode.

In order to allow physical devices to connect to the emulators I run on my development machine, I've changed the configuration so that the emulators run using that machine's local IP on my local network. (I specify this IP via a Dart environment variable.)

firebase.json

{
  // ...
  "emulators": {
    "auth": {
      "host": "0.0.0.0",  // this is to avoid having to hard-code my local IP, which might change
      "port": 9099
    },
    "firestore": {
      "host": "0.0.0.0",
      "port": 8080
    },
    // ...
  }
}

main.dart

if (kDebugMode) {
  const emulatorHost =
      String.fromEnvironment("EMULATOR_HOST", defaultValue: "localhost");
  FirebaseAuth.instance.useAuthEmulator(emulatorHost, 9099);
  FirebaseFirestore.instance.useFirestoreEmulator(emulatorHost, 8080);
}

To test the web version on my app, I start the emulators and run the web app through Android Studio, all on the same app. The app is able to communicate with the Auth emulator, no problem.

However, when I run the app in debug mode on my physical Android device or on an Android emulator, whenever it tries to communicate to the Auth emulator (namely in the sign-in screen, which is given by firebase_ui_auth), I get this error:

com.google.firebase.FirebaseException: An internal error has occurred. [ Cleartext HTTP traffic to <my local ip> not permitted ]

(Curiously, this only happens with the Auth emulator, because if I bypass any auth functionality, the Android app connects without problems to the Firestore emulator.)

As far as I understand, this means the app is trying to communicate to the emulator via non-encrypted HTTP traffic, which Android doesn't allow (for this app configuration).

The suggested solutions I've seen (Error connecting to local Firebase functions emulator from Flutter app, Flutter Cleartext HTTP traffic not permitted) all involve removing this restriction, either by allowing clear-text HTTP traffic app-wide

<application android:usesCleartextTraffic="true" />

or by just allowing clear text traffic to the specific IP the emulators are running on

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain>10.0.2.2</domain>
    </domain-config>
</network-security-config>

I do not want to use either of these solutions, because I don't want to enable clear-text HTTP just because I need it for local testing with Firebase emulators, and I don't want to have to hard-code my local IP, which might change, in an Android xml file somewhere.

Is there an alternative solution that doesn't have these issues? Can I make the SDK connect to the emulator via HTTPS, for example?


As a temporary solution/band-aid, for now I'm enabling clear-text HTTP app-wide but only for the debug flavour of the app, by applying the solution mentioned above to the Android manifest in android/app/src/debug instead of android/app/src/main.

Anakhand
  • 2,838
  • 1
  • 22
  • 50
  • 1
    GitHub FlutterFire had closed issue about this [link](https://github.com/firebase/flutterfire/issues/9371), and the solution is directed to that stack overflow solutions that you mentioned above [link](https://stackoverflow.com/questions/62984527/error-connecting-to-local-firebase-functions-emulator-from-flutter-app/62985709#62985709). lol, this kind of annoying because it will permanently enabled on the app. I think your band aid solution by put it in debug is better. Yet, it does better if FlutterFire has more solid solution about this that not required user to modify anything. – Ryde Jun 07 '23 at 23:38

0 Answers0