如何使用带有flutter的Firebase手机身份验证



我正在尝试使用flutter和firebase制作一个应用程序。我正在使用FirebaseAuth进行注册和登录。我将手机号码和密码作为输入,创建一个带有电话号码的虚拟电子邮件,并使用firebase auth-signInWithEmailPassword登录。我想做的是第一次用户注册时,我想把otp发送到那个号码,如果号码经过验证,我想用那个假电子邮件和密码注册。任何实现这一目标的想法。我尝试了一些东西,但用户正在注册,即使otp是错误的。

String email = '';
String password = '';
String name = '';
String contact = '';
String error = '';
String smsCode = '';
String verificationId;
bool loading = false;
Future<void> verifyPhone() async {
print('Inside verify phone');
final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
this.verificationId = verId;
};
final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
this.verificationId = verId;
print('Inside code sent');
smsCodeDialog(context).then((value) {
print('Signed in');
});
};
final PhoneVerificationCompleted verifiedSuccess =
(AuthCredential credential) {
print('verified');
};
final PhoneVerificationFailed verificationFailed =
(AuthException exception) {
print('${exception.message}');
};
if (_formKey.currentState.validate()) {
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: '+91 ' + contact,
timeout: const Duration(seconds: 10),
verificationCompleted: verifiedSuccess,
verificationFailed: verificationFailed,
codeSent: smsCodeSent,
codeAutoRetrievalTimeout: autoRetrieve,
);
}
}
Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter SMS Code'),
content: TextField(
onChanged: (value) {
this.smsCode = value;
},
),
contentPadding: EdgeInsets.all(10),
actions: <Widget>[
TextButton(
onPressed: () async {
dynamic result =
await _auth.register(email, password, name, contact);
if (result == null) {
Navigator.pop(context);
setState(() {
loading = false;
error = "Already registered or Invalid Details.";
});
} else {
Navigator.pop(context);
Navigator.pushNamedAndRemoveUntil(
context, '/', (Route<dynamic> route) => false);
}
},
child: Text('Register',
style: GoogleFonts.abhayaLibre(
textStyle: TextStyle(
fontSize: 24, color: Colors.green[900]))))
],
);
});
}

在提交表单时,我调用verifyPhone方法。

Future<bool> signIn() async {
try {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: smsCode,
);
final AuthResult userResult =
await _auth.signInWithCredential(credential);
final FirebaseUser currentUser = await _auth.currentUser();
final document =
Firestore().collection("users").document(currentUser.uid);
final documentSnapshot = await document.get();
if (!documentSnapshot.exists) {
await document.setData({
"id": currentUser.uid,
"number": phoneNumber,
});
}
return true;
} catch (e) {
return false;
}

}

onPressed: () async {
if (_smsController.text.isEmpty) {
widget.scaffoldKey.currentState
.showSnackBar(SnackBar(
content: Text(
"Please enter your SMS code"),
duration: Duration(seconds: 2),
));
return;
}
await _auth
.currentUser()
.then((user) async {
await signIn()
.then((bool isSignedIn) async {
if (isSignedIn) {
Navigator.of(context)
.pushAndRemoveUntil();
} else {
widget.scaffoldKey.currentState
.showSnackBar(SnackBar(
content:
Text("Incorrect Code"),
duration:
Duration(seconds: 2),
));
}
});
});
},

在这里,我可以向您展示一个最小的例子,它也使用firestore为用户存储额外的信息,每当按下短信对话框的按钮时,onPressed就会被触发

以下是如何使用带有flutter的Firebase电话身份验证的完整答案

  • 启用Firebase项目的电话号码登录

登录/注册屏幕

import 'package:flutter/material.dart';
import 'package: ../auth_provider.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatefulWidget {
static const String id = 'Login-Screen';
const LoginScreen({key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
TextEditingController _phoneNumberController = TextEditingController();
bool _validPhoneNumber = false;
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthProvider>(context);
return Scaffold(
// resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Visibility(
visible: '${auth.error}Please Try Again' =='Invalid Code'? true:false,
child: Container(
child: Column(
children: [
Text(auth.error,
style: TextStyle(
color: Colors.red,
fontSize: 15,
),
),
SizedBox(height: 5,),
],
),
),
),
Text(
'Login',
style:
TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
), Text(
'Enter Your Phone Number',
style:
TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
SizedBox(
height: 30,
),
TextField(
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
prefixText: '+92',
prefixStyle: TextStyle(color: Colors.black),
labelText: 'Enter Your Mobile Number',
labelStyle: TextStyle(
color: Colors.black,
),
),
autofocus: true,
keyboardType: TextInputType.phone,
maxLength: 11,
controller: _phoneNumberController,
onChanged: (value) {
if (value.length == 11) {
setState(() {
_validPhoneNumber = true;
});
} else {
setState(() {
_validPhoneNumber = false;
});
}
},
),
SizedBox(
height: 10,
),
Row(
children: [
Expanded(
child: AbsorbPointer(
absorbing: _validPhoneNumber ? false : true,
// ignore: deprecated_member_use
child: FlatButton(
onPressed: () {
String number =
'+92${_phoneNumberController.text}';
auth.verifyPhone(
context: context,
number: number,
).then((value){
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)
);
// _phoneNumberController.clear();
setState(() {
auth.loading = false;
});
});
},
color: _validPhoneNumber
? Colors.greenAccent
: Colors.grey,
child:
auth.loading ? CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white)
):
Text(
_validPhoneNumber
? 'CONTINUE'
: 'ENTER PHONE NUMBER',
style: TextStyle(color: Colors.black),
),
),
),
),
],
),
],
),
),
),
),
);
}
}

身份验证码

Future<void> verifyPhone({BuildContext context, String number}) async {
this.loading = true;
notifyListeners();
final PhoneVerificationCompleted verificationCompleted =
(PhoneAuthCredential credential) async {
this.loading = false;
notifyListeners();
await _auth.signInWithCredential(credential);
};
final PhoneVerificationFailed verificationFailed =
(FirebaseAuthException e) {
this.loading = false;
print(e.code);
this.error = e.toString();
notifyListeners();
};
final PhoneCodeSent smsOtpSend = (String verId, int resendToken) async {
this.verificationId = verId;
smsOtpDialog(context, number);
//  smsOtpDialog(context, number);
};
try {
_auth.verifyPhoneNumber(
phoneNumber: number,
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: smsOtpSend,
codeAutoRetrievalTimeout: (String verId) {
this.verificationId = verId;
},
);
} catch (e) {
this.error = e.toString();
this.loading = false;
notifyListeners();
print(e);
}
}

OPT屏幕

Future<bool> smsOtpDialog(BuildContext context, String number) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Column(
children: [
Text('Verification Code'),
SizedBox(
height: 6,
),
Text(
'Enter 6 digit Code received by SMS',
style: TextStyle(color: Colors.grey, fontSize: 12),
)
],
),
content: Container(
height: 85,
child: TextField(
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
maxLength: 6,
onChanged: (value) {
this.smsOtp = value;
},
),
),
actions: [
// ignore: deprecated_member_use
FlatButton(
onPressed: () async {
try {
PhoneAuthCredential phoneAuthCredential =
PhoneAuthProvider.credential(
verificationId: verificationId, smsCode: smsOtp);
final User user =
(await _auth.signInWithCredential(phoneAuthCredential))
.user;
if (user != null) {
this.loading = false;
notifyListeners();
_vendorServices.getVendorById(user.uid).then((snapShot) {
if (snapShot.exists) {
if (this.screen == 'Login') {
if(snapShot['address']!=null){
Navigator.pushReplacementNamed(context, HomeScreen.id);
}
Navigator.pushReplacementNamed(context, HomeScreen.id);
} else {
print(
'{$locationData.latitude} : $locationData.longitude}');
updateVendor(id: user.uid, number: user.phoneNumber, shopName: user.displayName);
Navigator.pushReplacementNamed(context, HomeScreen.id);
}
} else {
_createVendor(id: user.uid, number: user.phoneNumber, shopName: user.displayName);
Navigator.pushReplacementNamed(context, HomeScreen.id);
}
});
} else {
print('Login Failed');
}
} catch (e) {
this.error = 'Invalid Code';
notifyListeners();
print(e.toString());
Navigator.of(context).pop();
}
},
child:
Text('Done', style: TextStyle(color: Colors.greenAccent)),
),
],
);
}).whenComplete(() {
this.loading = false;
notifyListeners();
});
}

有关更多详细信息,请查看官方文档https://firebase.google.com/docs/auth/android/phone-auth

相关内容

  • 没有找到相关文章

最新更新