简体   繁体   English

我正在使用 firebase flutter 实现电话身份验证。 但是有一个问题

[英]I am implementing phone authentication using firebase flutter. But there's a problem

I want to sign in using phone verification SMS, whenever a new user opens the app he will enter his phone number and click on verify button, once it is clicked the user will receive a verification SMS in his phone which he will enter in the verification text field.我想使用手机验证短信登录,每当新用户打开应用程序时,他都会输入他的电话号码并点击验证按钮,一旦点击,用户将在他的手机中收到一条验证短信,他将在验证中输入文本域。 But when I run the app, it launches and when I enter the phone number and click on verify button, the app just shuts down itself instead of sending me the message.但是当我运行该应用程序时,它会启动,当我输入电话号码并单击验证按钮时,该应用程序只是自行关闭而不是向我发送消息。 Here's the code:这是代码:

    import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:sms_autofill/sms_autofill.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(title: 'Flutter Auth Demo'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  final FirebaseAuth _auth = FirebaseAuth.instance;
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  final TextEditingController _phoneNumberController = TextEditingController();
  final TextEditingController _smsController = TextEditingController();
  String _verificationId;
  final SmsAutoFill _autoFill = SmsAutoFill();

  void verifyPhoneNumber() async {

  //  Callback for when the user has already previously signed in with this phone no. on this device
    PhoneVerificationCompleted verificationCompleted = (PhoneAuthCredential phoneAuthCredential) async {
      await _auth.signInWithCredential(phoneAuthCredential);
      showSnackbar("Phone no. automatically verified and user signed in as: ${_auth.currentUser.uid}");
    };

    PhoneVerificationFailed verificationFailed = (FirebaseAuthException authException) {
      showSnackbar('Phone number verification failed. Code: ${authException.code}. Message:${authException.message}');
    };

  //  Callback for when the code is sent
    PhoneCodeSent phoneCodeSent = (String verificationId,[int forceResendToken]) async {
      showSnackbar("Please check your phone for the verification code.");
      _verificationId = verificationId;
    };

    PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = (String verificationId) async {
      showSnackbar("Verification Code: "+verificationId);
      _verificationId = verificationId;
    };
    try {
      await _auth.verifyPhoneNumber(
          phoneNumber: _phoneNumberController.text,
          timeout: const Duration(seconds: 5),
          verificationCompleted: verificationCompleted,
          verificationFailed: verificationFailed,
          codeSent: phoneCodeSent,
          codeAutoRetrievalTimeout: codeAutoRetrievalTimeout
      );
    } catch(e) {
      showSnackbar("Failed to verify phone number: ${e}");
    }
  }
  void showSnackbar(String message) {
    _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
  }

  void signInWithPhoneNumber() async {
    try{
      final AuthCredential credential = PhoneAuthProvider.credential(
          verificationId: _verificationId,
          smsCode: _smsController.text
      );
      final User user = (await _auth.signInWithCredential(credential)).user;
      showSnackbar("Successfully signed in with uid: ${user.uid}");
    }catch(e){
      showSnackbar("Failed to sign in: "+e.toString());
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        key: _scaffoldKey,
        resizeToAvoidBottomPadding: false,
        body: Padding(padding: const EdgeInsets.all(8),
          child: Padding(
              padding: EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  TextFormField(
                    controller: _phoneNumberController,
                    decoration: const InputDecoration(
                        labelText: 'Phone number (+xx xxx-xxx-xxxx)'
                    ),
                  ),
                  Container(
                    padding: EdgeInsets.symmetric(vertical: 16.0),
                    alignment: Alignment.center,
                    child: RaisedButton(
                        child: Text("Get current number"),
                        onPressed: () async => {
                          _phoneNumberController.text = await _autoFill.hint,
                          print("_phoneNumberController.text: ${_phoneNumberController.text}")
                        },
                        color: Colors.greenAccent[700],
                    ),
                  ),
                  Container(
                    padding: EdgeInsets.symmetric(vertical: 16.0),
                    alignment: Alignment.center,
                    child: RaisedButton(
                        color: Colors.greenAccent[400],
                        child: Text("Verify Number"),
                        onPressed: () async {
                          verifyPhoneNumber();
                          Navigator.of(context).pop();
                        }
                    ),
                  ),
                  TextFormField(
                    controller: _smsController,
                    decoration: const InputDecoration(labelText: 'Verification Code'),
                  ),
                  Container(
                    padding: EdgeInsets.only(top: 16.0),
                    alignment: Alignment.center,
                    child: RaisedButton(
                      color: Colors.greenAccent[200],
                      onPressed: () async {
                        signInWithPhoneNumber();
                      },
                      child: Text("Sign In"),
                    ),
                  ),
                ],
              )
          ),
        )
    );
  }
}

and the error that appears during the app shut down is "Lost device connection":并且在应用关闭期间出现的错误是“丢失设备连接”:

E/AndroidRuntime(18860): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196) E/AndroidRuntime(18860): at java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/AndroidRuntime(18860): at java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/AndroidRuntime(18860): ... 12 more I/Process (18860): Sending signal. E/AndroidRuntime(18860): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196) E/AndroidRuntime(18860): at java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/AndroidRuntime(18860) : 在 java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/AndroidRuntime(18860): ... 12 更多 I/Process (18860): 发送信号。 PID: 18860 SIG: 9 PID:18860 SIG:9

From this code snippet remove Navigator.of(context).pop();从此代码片段中删除Navigator.of(context).pop(); it makes your app pop out the only screen which closes the application and eventually it shows lost the connection as app is no longer visible.它使您的应用程序弹出关闭应用程序的唯一屏幕,并最终显示失去连接,因为应用程序不再可见。

Container(
 padding: EdgeInsets.symmetric(vertical: 16.0),
 alignment: Alignment.center,
    child: RaisedButton(
      color: Colors.greenAccent[400],
        child: Text("Verify Number"),
           onPressed: () async {
              verifyPhoneNumber();
              Navigator.of(context).pop();
           }
         ),
       ),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM