1

I am following a tutorial on building a login page for users and for a few days now I have been stuck with a cleartext error.

In response I have noticed directions on creating a network_security_config file and adding to the AndroidManifest files, but these things made no difference.

Then I found a tutorial on hard-coding the Android emulator's settings, and this made a difference, but afterwards the error found is that users in the Firestore are not found at login attempts ... And so it becomes circular, with one thing or another.

The question I have is, is there a solution in January 2023 for overcoming the infamous cleartext error please? ... I thought I had got past this problem having got past this point before, but it seems that everything I did before doesn't work anymore.

Is there a CLI solution for setting up Android emulators and fixing their network security?

main.dart

const bool useEmulator = true;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  if (useEmulator == true) {
    await _connectToFirebaseEmulator();
  }  
  runApp(LoginScreen());
}

/// Connect to the firebase emulator for firestore and authentication
Future _connectToFirebaseEmulator() async {
  final localHostString = Platform.isAndroid ? '10.0.2.2' : 'localhost';

  FirebaseFirestore.instance.settings = Settings(
    host: '$localHostString:2080',
    sslEnabled: false,
    persistenceEnabled: false,
  );
  await auth.FirebaseAuth.instance.useAuthEmulator('http://$localHostString', 9080);
}
LoginPage.dart:

class LoginScreen extends StatelessWidget {
  LoginScreen({super.key});

  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();

  void signUserIn() async {
    await auth.FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text, password: passwordController.text);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: false,
        backgroundColor: Colors.blue[900],
        body: SafeArea(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Padding(padding: EdgeInsets.only(top: 0, bottom: 37)),

                TextField_Try(
                    hintText: 'Username',
                    obscureText: false,
                    controller: emailController),

                Padding(padding: EdgeInsets.only(top: 0, bottom: 0)),

                Padding(
                    padding: EdgeInsets.only(
                        top: 8.0, left: 8.0, right: 8.0, bottom: 28.0),
                    child: TextField_Try(
                      hintText: '**************',
                      obscureText: true,
                      controller: passwordController,
                    )),

                Padding(padding: EdgeInsets.only(bottom: 10)),

                ElevatedButton(onPressed: signUserIn, child: Text('Sign In')),

                Padding(padding: EdgeInsets.only(bottom: 25)),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Network-Config:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config xmlns:android="http://schemas.android.com/apk/res/android">
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">http://10.0.2.2</domain>
        </domain-config>
</network-security-config>

AndroidManifest - main:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:targetSandboxVersion="1"
    package="com.example.mathems_m">


    <uses-permission android:name="android.permission.INTERNET"></uses-permission>


   <application
        android:label="mathems_m"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
       android:usesCleartextTraffic="true"
       android:roundIcon="@android:interpolator/cycle"
       android:supportsRtl="true"
       android:allowBackup="true">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
       <meta-data
           android:name="com.google.android.gms.wallet.api.enabled"
           android:value="true" />
    </application>
</manifest>

My position is creating a user at the FIRECLOUD console (email + password) and then attempting to login with the created user's details. It hasn't worked out though things I have done have led to different error messages.

The current error message is:

E/flutter (20214): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: [firebase_auth/unknown] com.google.firebase.FirebaseException: An internal error has occurred. [ Invalid authority field:[http: ]
E/flutter (20214): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter (20214): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
E/flutter (20214): <asynchronous suspension>
E/flutter (20214): #2      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:367:43)
E/flutter (20214): <asynchronous suspension>
E/flutter (20214): #3      MethodChannelFirebaseAuth.signInWithEmailAndPassword (package:firebase_auth_platform_interface/src/method_channel/method_channel_firebase_auth.dart:500:12)
E/flutter (20214): <asynchronous suspension>
E/flutter (20214): #4      FirebaseAuth.signInWithEmailAndPassword (package:firebase_auth/src/firebase_auth.dart:584:9)
E/flutter (20214): <asynchronous suspension>
E/flutter (20214): #5      LoginScreen.signUserIn (package:choice_hi/screens/login.dart:15:5)
E/flutter (20214): <asynchronous suspension>
E/flutter (20214): 

The various differing error messages relate to the cleartext error.

Please advise me on a solution for overcoming the cleartext error 100%. Thank you.

mathems32
  • 115
  • 9
  • For Emulator: remove "http://" from firebaseAuth url, use only ip like "10.0.2.2" and port and check again. – Vishal Zaveri Jan 05 '23 at 02:33
  • Hi Vishal, Thank you for your response ... I did as you suggested and the error message given is: E/flutter (21033): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: [firebase_auth/unknown] com.google.firebase.FirebaseException: An internal error has occurred. [ Failed to connect to /10.0.2.2:9080 ] – mathems32 Jan 05 '23 at 14:41
  • await auth.FirebaseAuth.instance.useAuthEmulator('127.0.0.1', 9080); Can you try this? – Vishal Zaveri Jan 05 '23 at 14:59
  • In Android manifest file add property andriod:usesCleartextTraffic="true" In tag – Vishal Zaveri Jan 05 '23 at 15:02
  • I did: await auth.FirebaseAuth.instance.useAuthEmulator('127.0.0.1', 9080); ... Result: E/flutter (21033): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: [firebase_auth/unknown] com.google.firebase.FirebaseException: An internal error has occurred. [ Failed to connect to /10.0.2.2:9080 ] ... I believe the app/build.gradle minSdkVersion and targetSdkVersions make a difference ... How are yours set please? – mathems32 Jan 05 '23 at 15:12
  • check this one https://stackoverflow.com/questions/64801702/flutter-firebase-authentication-emulator-enabling – Vishal Zaveri Jan 05 '23 at 15:19
  • Thank you for the guidance, I am still working at it and wondering whether it is impossible to get this right in one go, ever ... The latest error message ask me to do some things, and I am unsure of exactly what: Attribute application@usesCleartextTraffic value=(true) from AndroidManifest.xml:11:18-53 is also present at AndroidManifest.xml:15:8-44 value=(false). Suggestion: add 'tools:replace="android:usesCleartextTraffic"' to element at AndroidManifest.xml:11:5-68 to override. – mathems32 Jan 05 '23 at 23:00
  • After the error message above, I changed things so that calls for cleartextTraffic are true in both places ... Still, I'd like to understand what I was being asked to do ... Slightly unclear ... It seems to be resolved now, as the login attempt response from Flutter is confirming the relevant user's uid: D/FirebaseAuth(22320): Notifying id token listeners about user ( Qlr566xptiSRaS6K0zSYyE0Ow332 ) ... Many thanks Vishal : ) – mathems32 Jan 05 '23 at 23:19
  • Most welcome. If it's working correctly just add required changes in answer so it's helps to other. Happy coding:) – Vishal Zaveri Jan 06 '23 at 01:59
  • Thank you Vishal, I will ... What I did just now was start all over again to see if I could set everything up in one go, because this issue always delays me ... I managed to get things up and running within a new Flutter project successfully within a few minutes ... To do so, I used Flutter's terminal commands to add Firebase and packages, and to add emulators, doing nothing manually except my build.gradle settings (33) ... Then, for my main AndroidManifest I added 1 line within for cleartext = true, and in my debug-AndroidManifest I added 1 line: – mathems32 Jan 06 '23 at 13:34
  • To my debug-AndroidManifest I added: – mathems32 Jan 06 '23 at 13:35
  • The main difference in my approach today was to let Flutter build Flutter by calling on the relevant commands within the Flutter terminal ... Google's Firebase docs confirm that each time the 'flutterfire configure' command is called, Flutter ensures that configuration is up to date and automatically adds the required gradle plugins ... The same promise of up-to-date configuration is probably consistent with all Flutter terminal commands that build onto Flutter apps automatically ... I trust that this info will help many others asking the same question ... Happy coding : ) – mathems32 Jan 06 '23 at 13:46
  • i am glad that you query resolved. just update additional details in my answer with links so it helps others. – Vishal Zaveri Jan 06 '23 at 13:49

2 Answers2

2

Okay, so in the end, I made useEmulator 'false' so that there's zero reliance on the _connectToFirebaseEmulator() method, which means I have found a solution that does not require a network_security_config.xml file ... To achieve my success I added Firebase to my project automatically, I added Firebase emulators automatically and each package for pubspec was added automatically using Flutter's terminal instead of alternative ways (executing 'flutter pub add firebase_core' in terminal - for example). Generally, relying on Flutter to build Flutter where the option is available.

build.gradle

android {
compileSdkVersion 33
ndkVersion ndkVersion

main-AndroidManifest

<application
    android:label="mathems_m"
    android:name="${applicationName}"
    android:icon="@mipmap/ic_launcher"
   android:usesCleartextTraffic="true"

debug-AndroidManifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mathems_m">
<meta-data
    android:value="true"/>
    <!-- The INTERNET permission is required for development. Specifically,
         the Flutter tool needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <application android:usesCleartextTraffic="true" />
</manifest>

That's about it really ... So, this shows how simple the Firebase-authentication can be to set up ... In minutes instead of days : )

mathems32
  • 115
  • 9
0

for simulator Add line before call auth function

FirebaseAuth.instance.useAuthEmulator('127.0.0.1', 9080);

Android - In Android main/menifest file for network issue handle

<application

android:usesCleartextTraffic="true" // Add line             
android:name="io.flutter.app.FlutterApplication"
android:label="firebaseauthexample"> 

</application>

iOS - iOS/runner/info.plist

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Vishal Zaveri
  • 1,372
  • 2
  • 5
  • 12