我正在尝试通过电话对用户进行身份验证,并且在使用flutter_bloc和存储库时,我使用的方法是:
verifyPhoneNumber
并输入电话号码(确定)。verificationId
或codeAutoRetrievalTimeout
回调中收到的codeSent
。BlocListener
发送到UI。在首先调用verifyPhoneNumber完成之前,我的方法在回调之前返回,因此它返回一个空字符串。
我做错了什么? 一如既往,非常感谢您的帮助。
Future<String> verifyPhoneNumber(String phoneNumber) async {
print('verifyPhoneNumber() started');
String verifyId;
await _firebaseAuth
.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(minutes: 0),
//error: Undefined class 'PhoneAuthCredential'.
// verificationCompleted: (PhoneAuthCredential credential) async {
verificationCompleted: (AuthCredential credential) {
},
//error: Undefined class 'FirebaseAuthException'.
// verificationFailed: (FirebaseAuthException e) {
verificationFailed: (AuthException e) {
if (e.code == 'invalid-phone-number') {
print(
'verifyPhoneNumber() -> verificationFailed -> The provided phone number is not valid.');
} else {
print(
'verifyPhoneNumber() -> verificationFailed :${e.message}');
}
// Handle other errors
},
codeAutoRetrievalTimeout: (String verificationId) {
// Auto-resolution timed out...
// verifyId = verificationId;
print(
'verifyPhoneNumber() -> codeAutoRetrievalTimeout callback called');
},
//error: The argument type 'Null Function(String, int)' can't be assigned to the parameter type 'void Function(String, [int])'.
// codeSent: (String verificationId, int resendToken) {
codeSent: (String verificationId, [int resendToken]) {
verifyId = verificationId;
print(
'verifyPhoneNumber() -> codeSent callback called : $verifyId'); // correct
return verifyId;
}
)
.then((value) {
print('verifyId is $verifyId'); // null
// return verifyId;
}).whenComplete(() => print('Complete'));
print('verifyPhoneNumber() ->returning verifyId: $verifyId');
return verifyId; // without it method doesn't return, with it returns null
}
答案 0 :(得分:0)
最终设法从Bloc正确使用了它。
方法是:
Future<void> verifyPhone(
{@required String phoneNumber,
@required Duration timeOut,
@required PhoneVerificationFailed phoneVerificationFailed,
@required PhoneVerificationCompleted phoneVerificationCompleted,
@required PhoneCodeSent phoneCodeSent,
@required PhoneCodeAutoRetrievalTimeout autoRetrievalTimeout}) async {
_firebaseAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: timeOut,
verificationCompleted: phoneVerificationCompleted,
verificationFailed: phoneVerificationFailed,
codeSent: phoneCodeSent,
codeAutoRetrievalTimeout: autoRetrievalTimeout);
}
Future<AuthResult> verifyAndLinkAuthCredentials(
{@required String verificationId, @required String smsCode}) async {
AuthCredential authCredential = PhoneAuthProvider.getCredential(
verificationId: verificationId, smsCode: smsCode);
// return _firebaseAuth.signInWithCredential(authCredential);
FirebaseUser user = await _firebaseAuth.currentUser();
return user.linkWithCredential(authCredential).catchError((e) {
print('UserRepository.verifyAndLinkAuthCredentials() error: $e');
// return;
});
}
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event) async* {
// phone verification
if (event is VerifyPhoneNumberEvent) {
print('VerifyPhoneNumberEvent received');
yield VerifyingState();
yield* _mapVerifyPhoneNumberToState(event);
}
if (event is PhoneCodeSentEvent) {
print('PhoneCodeSentEvent received');
yield OtpSentState();
}
if (event is VerificationCompletedEvent) {
print('VerificationCompletedEvent received');
yield VerificationCompleteState(firebaseUser: event.firebaseUser, isVerified: event.isVerified);
}
if (event is VerificationExceptionEvent) {
print('VerificationExceptionEvent received');
yield VerificationExceptionState(message: event.message);
}
if ( event is PhoneCodeAutoRetrievalTimeoutEvent){
yield PhoneCodeAutoRetrievalTimeoutState(verificationId: event.verificationId);
}
if(event is SendVerificationCodeEvent) {
yield VerifyingState();
yield*_mapVerificationCodeToState(event);
}
}
Stream<AuthenticationState> _mapVerifyPhoneNumberToState(VerifyPhoneNumberEvent event) async* {
print('_mapVerifyPhoneNumberToState V2 started');
final phoneVerificationCompleted = (AuthCredential authCredential) {
print('_mapVerifyPhoneNumberToState PhoneVerificationCompleted');
_userRepository.getCurrentUser().catchError((onError) {
print(onError);
}).then((user) {
add(VerificationCompletedEvent(firebaseUser: user, isVerified: true));
});
};
final phoneVerificationFailed = (AuthException authException) {
print('_mapVerifyPhoneNumberToState PhoneVerificationFailed');
print(authException.message);
add(VerificationExceptionEvent(onError.toString()));
};
final phoneCodeSent = (String verificationId, [int forceResent]) {
print('_mapVerifyPhoneNumberToState PhoneCodeSent');
this.verificationId = verificationId;
add(PhoneCodeSentEvent());
};
final phoneCodeAutoRetrievalTimeout = (String verificationId) {
print('_mapVerifyPhoneNumberToState PhoneCodeAutoRetrievalTimeout');
this.verificationId = verificationId;
add(PhoneCodeAutoRetrievalTimeoutEvent(verificationId: verificationId));
};
await _userRepository.verifyPhone(
phoneNumber: event.phoneNumber,
timeOut: Duration(seconds: 0),
phoneVerificationFailed: phoneVerificationFailed,
phoneVerificationCompleted: phoneVerificationCompleted,
phoneCodeSent: phoneCodeSent,
autoRetrievalTimeout: phoneCodeAutoRetrievalTimeout);
}
Stream<AuthenticationState> _mapVerificationCodeToState(SendVerificationCodeEvent event) async* {
print('_mapVerificationCodeToState started');
AuthResult result = await _userRepository.verifyAndLinkAuthCredentials(verificationId: verificationId, smsCode: event.smsCode)
.catchError((e){
print('verifyAndLinkAuthCredentials error: $e');
});
print(result);
if (result != null) {
yield VerificationCompleteState(firebaseUser: result.user, isVerified: true);
} else {
yield OtpExceptionState(message: "Invalid otp!", verificationId: verificationId);
}
}
希望这对其他人有帮助。 干杯。