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. PID: 18860 SIG: 9