I'm writing a flutter app that using phone authentication. I am runing the app currently on iPhone 12 simulator and when I testing the app and implement the phone number I am not receiving the 6 digit code from firebase as planed. I Think is because one of those mention resons.
(I don't have an apple developer account yet, so I gave a test number and code to firebase so when I will put the fake number I will still get the code to the app (not as push notification)).
Some dots of the app:
I have no problem to test the app on real device if needed.
I don't need to get the push notification right now, I can just print the verification code to the console so I will see that the code work.
I want to start the verification process right after I sent the phone number to this page (verification page)
right now I am using a full number without the area code.
I can use a fake number for the simulator? or I need a real one?.
Thank you, and hope you can help e with my problem.
this is my code (only the verification part):
// imports are here
enum Status { waiting, error }
class VerificationCode extends StatefulWidget {
const VerificationCode({Key? key, this.number}) : super(key: key);
final number;
@override
_VerificationCodeState createState() => _VerificationCodeState(number);
}
class _VerificationCodeState extends State<VerificationCode> {
late final phoneNumber;
final _verKey = GlobalKey<FormState>();
late String _verCode;
late double _formHeight;
final FirebaseAuth _auth = FirebaseAuth.instance;
var _verificationId;
var _status = Status.waiting;
_VerificationCodeState(this.phoneNumber); // storing the phone number from other page
@override
void initState() {
super.initState();
_verifyPhoneNumber();
}
Future _verifyPhoneNumber() async {
_auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
verificationCompleted: (phonesAuthCredentials) async {},
verificationFailed: (verificationFailed) async {},
codeSent: (verificationId, reseningToken) async {
setState(() {
_verificationId = verificationId;
print(_verificationId); // here I am printing the opt code so I will know what it is to use it
});
},
codeAutoRetrievalTimeout: (verificationId) async {});
}
Future _sendCodeToFirebase({String? code}) async {
if (_verificationId != null) {
var credential = PhoneAuthProvider.credential(
verificationId: _verificationId,
smsCode: code!,
);
await _auth
.signInWithCredential(credential)
.then((value) {
print("auth complete!");
})
.whenComplete(() {})
.onError((error, stackTrace) {
setState(() {
_verKey.currentState!.reset();
_status = Status.error;
});
});
}
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
if (size.height <= 736) {
_formHeight = (size.height * .05) + 6;
} else {
_formHeight = size.height * .048;
}
return Scaffold(
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).requestFocus(
FocusNode(),
),
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: size.height - 90,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Stack(
alignment: Alignment.topLeft,
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Padding(
padding: EdgeInsets.only(
top: size.height * .006,
left: size.width * .03,
),
child: SvgPicture.asset(
"assets/arrow-back.svg",
),
),
),
],
),
Padding(
padding: EdgeInsets.only(
top: size.height * .18,
),
child: Center(
child: Text(
"AppName",
style: TextStyle(
fontSize: size.width * .096,
letterSpacing: size.width * .026,
fontWeight: FontWeight.w300,
),
),
),
),
Padding(
padding: EdgeInsets.only(top: size.height * .015),
child: Center(
child: Container(
margin: EdgeInsets.symmetric(
horizontal: size.width * .045,
),
height: _formHeight,
child: Form(
key: _verKey,
child: TextFormField(
style: TextStyle(
fontSize: size.width * .035,
),
decoration: InputDecoration(
counterText: "",
contentPadding:
const EdgeInsets.fromLTRB(0, 10, 0, 0),
hintText: 'Verification Code',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(7.0),
borderSide: const BorderSide(
color: Colors.black,
width: 1.25,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(7.0),
borderSide: const BorderSide(
color: Colors.black,
width: 1.5,
),
),
),
autofocus: false,
keyboardType: TextInputType.number,
cursorColor: Colors.black,
textAlign: TextAlign.center,
onChanged: (input) async {
if (input.length == 6) {
_verCode = input;
_sendCodeToFirebase(code: _verCode);
}
},
maxLength: 6,
),
),
),
),
),
],
),
),
),
),
),
);
}
}
Firebase Phone Authentication on iOS requires some setup steps as mentioned in the docs . The step where it mentions you need to enable push notifications is required to verify that the request is coming from your app, it's called " Silent APNs notifications " because it happens silently without the user being aware of it, but in case of testing, the reCAPTCHA verification is used, read more on this step in the official Firebase iOS docs .
However, for the sake of testing on a simulator , you can indeed use a fake number and an SMS code that you have defined in Firebase console under Phone Authentication sign-in method.
First, you will need to setup reCAPTCHA verification for iOS as required by the Firebase SDK.
Second, add testing numbers testing Phone Auth locally :
Note the following on adding test numbers:
As for the format of phone numbers accepted by Firebase, it must have the country code, and follows the E.164 standard, starts with + followed by country code followed by the phone number.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.