Stuck zurück VerificationId von Future <String> Methode Flutter
Oct 23 2020
Ich versuche, Benutzer mit dem Telefon zu authentifizieren, und da ich flutter_bloc und Repository verwende, habe ich folgenden Ansatz:
- Ereignis mit Telefonnummer an Block senden (OK).
- Anruf
verifyPhoneNumberüber die Telefonnummer (OK). - Geben Sie die
verificationIdempfangenencodeAutoRetrievalTimeoutodercodeSentRückrufe zurück. - Senden Sie es
BlocListenermit einem Status an die Benutzeroberfläche . - Aktualisieren Sie die Benutzeroberfläche, um den Bestätigungscode einzugeben.
- Senden Sie smsCode und verificationId an eine andere Methode, um das AuthCredential des Telefons mit dem Benutzer zu verknüpfen.
Meine Methode wird zurückgegeben, bevor Rückrufe aufgerufen werden, da verifyPhoneNumber zuerst abgeschlossen wird, sodass eine Nullzeichenfolge zurückgegeben wird.
Was mache ich falsch? Wie immer vielen Dank für Ihre Hilfe.
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
}
Antworten
Vincenzo Oct 25 2020 at 03:13
Endlich geschafft, es richtig von Bloc zu verwenden.
Methoden sind:
UserRepository
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;
});
}
Rückrufe werden in Block-Streams definiert:
@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);
}
}
Hoffe das hilft anderen. Prost.