一次性验证后Flutter Android App崩溃

时间:2019-10-01 21:24:51

标签: firebase flutter dart

我刚按照Firebase建议的步骤将firebase导入到flutter应用程序中,同时将应用程序添加到firebase项目中。然后,我为PhoneAuth编写了代码。在运行该应用程序时,我得到的是OTP,但是当我输入OTP并单击调用“ signInwithcredential()”方法的按钮时,该应用程序将崩溃。 这是日志-

V/FA      (20586): Inactivity, disconnecting from the service
V/BoostFramework(20586): BoostFramework() : mPerf = com.qualcomm.qti.Performance@8c86bf5
I/art     (20586): Do partial code cache collection, code=28KB, data=30KB
I/art     (20586): After code cache collection, code=27KB, data=29KB
I/art     (20586): Increasing code cache capacity to 128KB
W/BiChannelGoogleApi(20586): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzak@9cb0748
W/BiChannelGoogleApi(20586): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzak@9cb0748
E/JavaBinder(20586): *** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
E/JavaBinder(20586): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/util/ArrayMap;
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzam.zzc(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzam.zzde(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzam.zzdd(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzan.zzdf(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzm.isAnonymous(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzat.zzi(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.internal.zzat.zzg(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.FirebaseAuth.zza(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.FirebaseAuth$zzb.zza(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.api.internal.zzcv.zzdx(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.api.internal.zzen.zzen(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.api.internal.zzen.zza(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.api.internal.zzep.zza(Unknown Source)
E/JavaBinder(20586):    at com.google.firebase.auth.api.internal.zzdx.dispatchTransaction(Unknown Source)
E/JavaBinder(20586):    at com.google.android.gms.internal.firebase_auth.zza.onTransact(Unknown Source)
E/JavaBinder(20586):    at android.os.Binder.execTransact(Binder.java:569)
E/JavaBinder(20586): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.util.ArrayMap" on path: DexPathList[[zip file "/data/app/phoneauth.abc.cpm.mittalphoneauth-2/base.apk"],nativeLibraryDirectories=[/data/app/phoneauth.abc.cpm.mittalphoneauth-2/lib/arm64, /data/app/phoneauth.abc.cpm.mittalphoneauth-2/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
E/JavaBinder(20586):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:74)
E/JavaBinder(20586):    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
E/JavaBinder(20586):    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
E/JavaBinder(20586):    ... 16 more
W/System.err(20586): java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/util/ArrayMap;
W/System.err(20586):    at com.google.firebase.auth.internal.zzam.zzc(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzam.zzde(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzam.zzdd(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzan.zzdf(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzm.isAnonymous(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzat.zzi(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.internal.zzat.zzg(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.FirebaseAuth.zza(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.FirebaseAuth$zzb.zza(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.api.internal.zzcv.zzdx(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.api.internal.zzen.zzen(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.api.internal.zzen.zza(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.api.internal.zzep.zza(Unknown Source)
W/System.err(20586):    at com.google.firebase.auth.api.internal.zzdx.dispatchTransaction(Unknown Source)
W/System.err(20586):    at com.google.android.gms.internal.firebase_auth.zza.onTransact(Unknown Source)
W/System.err(20586):    at android.os.Binder.execTransact(Binder.java:569)
W/System.err(20586): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.util.ArrayMap" on path: DexPathList[[zip file "/data/app/phoneauth.abc.cpm.mittalphoneauth-2/base.apk"],nativeLibraryDirectories=[/data/app/phoneauth.abc.cpm.mittalphoneauth-2/lib/arm64, /data/app/phoneauth.abc.cpm.mittalphoneauth-2/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
W/System.err(20586):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:74)
W/System.err(20586):    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
W/System.err(20586):    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
W/System.err(20586):    ... 16 more
E/JavaBinder(20586): Forcefully exiting
Lost connection to device.

这是我的main.dart文件-

import 'dart:ffi';

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Phone Auth'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String phoneNumber;
  String smsOTP;
  String verificationId;
  String errorMessage = '';
  FirebaseAuth _auth = FirebaseAuth.instance;

  Future<Void> verifyPhoneNumber() async {
    final PhoneCodeSent smscodesent = (String verId, [int forcecodesent]) {
      this.verificationId = verId;
      smsOTPDialog(context).then((value) {
        print("sign in");
      });
    };

    try {
      await _auth.verifyPhoneNumber(
          phoneNumber: this.phoneNumber,
          timeout: const Duration(seconds: 30),
          verificationCompleted: (AuthCredential phoneAuthCredential) {
            print(phoneAuthCredential);
          },
          verificationFailed: (AuthException exception) {
            print(exception.message);
          },
          codeSent: smscodesent,
          codeAutoRetrievalTimeout: (String verid) {
            this.verificationId = verid;
          });
    } catch (e) {
      print(e.toString());
    }
  }

  Future<bool> smsOTPDialog(BuildContext context) {
    return showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return new AlertDialog(
            title: Text('Enter SMS Code'),
            content: Container(
              height: 85,
              child: Column(children: [
                TextField(
                  onChanged: (value) {
                    this.smsOTP = value;
                  },
                ),
                (errorMessage != ''
                    ? Text(
                        errorMessage,
                        style: TextStyle(color: Colors.red),
                      )
                    : Container())
              ]),
            ),
            contentPadding: EdgeInsets.all(10),
            actions: <Widget>[
              FlatButton(
                child: Text('Done'),
                onPressed: () {
                  _auth.currentUser().then((user) {
                    if (user != null) {
                      Navigator.of(context).pop();
                      Navigator.of(context).pushReplacementNamed('/homepage');
                    } else {
                      signIn();
                    }
                  });
                },
              )
            ],
          );
        });
  }

  signIn() async {
    try {
      final AuthCredential credential = PhoneAuthProvider.getCredential(
        verificationId: verificationId,
        smsCode: smsOTP,
      );

      _auth.signInWithCredential(credential).then((AuthResult value) {
        if (value.user != null) {
          setState(() {
            print("authentication successful");
          });
        } else {
          setState(() {
            print("invalid authentication");
          });
        }
      });
    } catch (e) {
      print(e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(10),
              child: TextField(
                decoration: InputDecoration(
                    hintText: 'Enter Phone Number Eg. +910000000000'),
                onChanged: (value) {
                  this.phoneNumber = value;
                },
              ),
            ),
            (errorMessage != ''
                ? Text(
              errorMessage,
              style: TextStyle(color: Colors.red),
            )
                : Container()),
            SizedBox(
              height: 10,
            ),
            RaisedButton(
              onPressed: () {
                verifyPhoneNumber();
              },
              child: Text('Verify'),
              textColor: Colors.white,
              elevation: 7,
              color: Colors.blue,
            )
          ],
        ),
      ),
    );
  }
}

我在pubspec.yaml-

中添加的依赖项
firebase_auth: ^0.14.0+5
firebase_core: ^0.4.0+9

项目级别的build.gradle文件

buildscript {
    ext.kotlin_version = '1.2.71'
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:3.2.1'
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

应用程序级“ build.Gradle”文件

    def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 28

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "****************************"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.firebase:firebase-analytics:17.2.0'
}
apply plugin: 'com.google.gms.google-services'

用户正在使用该电话号码在Firebase中创建,但应用程序在通过OTP签名后立即崩溃。

2 个答案:

答案 0 :(得分:0)

将这两行添加到android / gradle.properties文件中,为我解决了此问题:

android.useAndroidX=true
android.enableJetifier=true

答案 1 :(得分:0)

我通过将Flutter项目迁移到AndroidX解决了该问题。供参考,请遵循this guide