I make one page to register a phone number and then verify the number on a second page. Now my problem is I can send the phone number just through the following code:
await Navigator.pushNamed(context, '/otpScreen', arguments: '$_dialCode${_contactEditingController.text}');
But I'm also need to send data of TextEditingController (nameController) values from this page:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:onefrist/testjust/screens/login_screen/widget/country_picker.dart';
import 'package:onefrist/testjust/screens/login_screen/widget/custom_button.dart';
import 'package:onefrist/testjust/screens/otp_screen/otp_screen.dart';
import '../../../LawsOfNewUser.dart';
import '../../../loginpage.dart';
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _contactEditingController = TextEditingController();
final nameController = TextEditingController();
final passwordController = TextEditingController();
var _dialCode = '';
//Login click with contact number validation
Future<void> clickOnLogin(BuildContext context) async {
if (_contactEditingController.text.isEmpty) {
showErrorDialog(context, 'Contact number can\'t be empty.');
} else {
final responseMessage =
await Navigator.pushNamed(context, '/otpScreen', arguments: '$_dialCode${_contactEditingController.text}');
if (responseMessage != null) {
showErrorDialog(context, responseMessage as String);
}
}
}
//callback function of country picker
void _callBackFunction(String name, String dialCode, String flag) {
_dialCode = dialCode;
}
//Alert dialogue to show error and response
void showErrorDialog(BuildContext context, String message) {
// set up the AlertDialog
final CupertinoAlertDialog alert = CupertinoAlertDialog(
title: const Text('Error'),
content: Text('\n$message'),
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('Yes'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
//build method for UI Representation
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(16.0),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: screenHeight * 0.05,
),
Image.asset(
'assets/images/registration.png',
height: screenHeight * 0.3,
fit: BoxFit.contain,
),
SizedBox(
height: screenHeight * 0.02,
),
const Text(
'Login',
style: TextStyle(fontSize: 28, color: Colors.black),
),
SizedBox(
height: screenHeight * 0.02,
),
const Text(
'Enter your mobile number to receive a verification code',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
SizedBox(
height: screenHeight * 0.04,
),
Container(
margin: EdgeInsets.symmetric(horizontal: screenWidth > 600 ? screenWidth * 0.2 : 16),
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
// ignore: prefer_const_literals_to_create_immutables
boxShadow: [
const BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
borderRadius: BorderRadius.circular(16.0)),
child: Column(
children: [
Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.symmetric(horizontal: 8.0),
height: 45,
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromARGB(255, 253, 188, 51),
),
borderRadius: BorderRadius.circular(36),
),
child: Row(
// ignore: prefer_const_literals_to_create_immutables
children: [
CountryPicker(
callBackFunction: _callBackFunction,
headerText: 'Select Country',
headerBackgroundColor: Theme.of(context).primaryColor,
headerTextColor: Colors.white,
),
SizedBox(
width: screenWidth * 0.01,
),
Expanded(
child: TextField(
decoration: const InputDecoration(
hintText: 'Contact Number',
),
controller: _contactEditingController,
keyboardType: TextInputType.number,
inputFormatters: [LengthLimitingTextInputFormatter(10)],
),
),
],
),
),
const SizedBox(
height: 8,
),
Container(
// width: 280,
padding: EdgeInsets.all(5.0),
child: TextField(
maxLength: 8,
controller: nameController,
autocorrect: true,
decoration: InputDecoration(
prefixIcon:Icon(Icons.account_circle),
border: OutlineInputBorder(),
labelText: 'Enter_Your_Name_Here',
),
)
),
CustomButton(clickOnLogin),
],
),
)
],
),
),
),
),
);
}
}
To this page:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:firebase_auth/firebase_auth.dart';
import 'package:pin_entry_text_field/pin_entry_text_field.dart';
// ignore: must_be_immutable
class OtpScreen extends StatefulWidget {
bool _isInit = true;
var _contact = '';
@override
_OtpScreenState createState() => _OtpScreenState();
}
class _OtpScreenState extends State<OtpScreen> {
String phoneNo;
String smsOTP;
String verificationId;
String errorMessage = '';
final FirebaseAuth _auth = FirebaseAuth.instance;
Timer _timer;
//this is method is used to initialize data
@override
void didChangeDependencies() {
// print(nameController.text);
super.didChangeDependencies();
// Load data only once after screen load
if (widget._isInit) {
widget._contact = '${ModalRoute.of(context).settings.arguments as String}';
generateOtp(widget._contact);
widget._isInit = false;
}
}
//dispose controllers
@override
void dispose() {
super.dispose();
}
//build method for UI
@override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.all(16.0),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: screenHeight * 0.05,
),
Image.asset(
'assets/images/logo.png',
width: screenWidth * 0.7,
fit: BoxFit.contain,
),
SizedBox(
height: screenHeight * 0.05,
),
SizedBox(
height: screenHeight * 0.02,
),
const Text(
'Verification',
style: TextStyle(fontSize: 28, color: Colors.black),
),
SizedBox(
height: screenHeight * 0.02,
),
Text(
'Enter A 6 digit number that was sent to ${widget._contact}',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 18,
color: Colors.black,
),
),
SizedBox(
height: screenHeight * 0.04,
),
Container(
margin: EdgeInsets.symmetric(horizontal: screenWidth > 600 ? screenWidth * 0.2 : 16),
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
// ignore: prefer_const_literals_to_create_immutables
boxShadow: [
const BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
borderRadius: BorderRadius.circular(16.0)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.only(left: screenWidth * 0.025),
child: PinEntryTextField(
fields: 6,
onSubmit: (text) {
smsOTP = text as String;
},
),
),
SizedBox(
height: screenHeight * 0.04,
),
GestureDetector(
onTap: () {
verifyOtp();
},
child: Container(
margin: const EdgeInsets.all(8),
height: 45,
width: double.infinity,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 253, 188, 51),
borderRadius: BorderRadius.circular(36),
),
alignment: Alignment.center,
child: const Text(
'Verify',
style: TextStyle(color: Colors.black, fontSize: 16.0),
),
),
),
],
),
)
],
),
),
),
),
);
}
//Method for generate otp from firebase
Future<void> generateOtp(String contact) async {
final PhoneCodeSent smsOTPSent = (String verId, [int forceCodeResend]) {
verificationId = verId;
};
try {
await _auth.verifyPhoneNumber(
phoneNumber: contact,
codeAutoRetrievalTimeout: (String verId) {
verificationId = verId;
},
codeSent: smsOTPSent,
timeout: const Duration(seconds: 60),
verificationCompleted: (AuthCredential phoneAuthCredential) {},
verificationFailed: (AuthException exception) {
// Navigator.pop(context, exception.message);
});
} catch (e) {
handleError(e as PlatformException);
// Navigator.pop(context, (e as PlatformException).message);
}
}
//Method for verify otp entered by user
Future<void> verifyOtp() async {
if (smsOTP == null || smsOTP == '') {
showAlertDialog(context, 'please enter 6 digit otp');
return;
}
try {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: smsOTP,
);
final AuthResult user = await _auth.signInWithCredential(credential);
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.user.uid == currentUser.uid);
Navigator.pushReplacementNamed(context, '/homeScreen');
} catch (e) {
handleError(e as PlatformException);
}
}
//Method for handle the errors
void handleError(PlatformException error) {
switch (error.code) {
case 'ERROR_INVALID_VERIFICATION_CODE':
FocusScope.of(context).requestFocus(FocusNode());
setState(() {
errorMessage = 'Invalid Code';
});
showAlertDialog(context, 'Invalid Code');
break;
default:
showAlertDialog(context, error.message);
break;
}
}
//Basic alert dialogue for alert errors and confirmations
void showAlertDialog(BuildContext context, String message) {
// set up the AlertDialog
final CupertinoAlertDialog alert = CupertinoAlertDialog(
title: const Text('Error'),
content: Text('\n$message'),
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
}
And receive the data sent from the first page into the second page.
If anyone knows the solution please help me. I try to solve it.