Parado de retornar verificationId do método Future <String> Flutter
Oct 23 2020
Estou tentando autenticar o usuário com telefone e, como estou usando flutter_bloc e Repositório, a abordagem que estou adotando é:
- Enviar evento com número de telefone para o Bloco (OK).
- Ligue
verifyPhoneNumberpassando o número do telefone (OK). - Retorne o
verificationIdrecebido de umcodeAutoRetrievalTimeoutou decodeSentretornos de chamada. - Envie para a interface do usuário
BlocListenercom um estado. - Atualize a IU para inserir o código de verificação.
- Envie smsCode e verificationId para outro método para vincular o telefone AuthCredential ao usuário.
Meu método retorna antes que os retornos de chamada sejam chamados, conforme verifyPhoneNumber é concluído primeiro, portanto, ele está retornando uma String nula.
O que estou fazendo de errado? Como sempre, muito obrigado pela sua ajuda.
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
}
Respostas
Vincenzo Oct 25 2020 at 03:13
Finalmente consegui usá-lo corretamente do Bloc.
Os métodos são:
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;
});
}
Retornos de chamada são definidos em fluxos de bloco:
@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);
}
}
Espero que isso ajude outras pessoas. Felicidades.
O que significa um erro “Não é possível encontrar o símbolo” ou “Não é possível resolver o símbolo”?
George Harrison ficou chateado por suas letras de 'Hurdy Gurdy Man' de Donovan não terem sido usadas