0

我正在尝试使用 Flutter Bloc 模式实现 Firebase 电话授权。我有以下代码

import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:firebase_auth/firebase_auth.dart';
import './bloc.dart';

class AuthBloc extends Bloc<AuthEvent, AuthState> {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  @override
  AuthState get initialState => AuthNotStarted();

  @override
  Stream<AuthState> mapEventToState(
    AuthEvent event,
  ) async* {
    if (event is VerifyPhone) {
      yield* _mapVerifyPhoneToState(event);
    }
  }

  Stream<AuthState> _mapVerifyPhoneToState(VerifyPhone event) async* {
    yield AuthStarted();
    _auth.verifyPhoneNumber(
        phoneNumber: "+" + event.phoneNumber,
        timeout: Duration(seconds: 60),
        verificationCompleted: (AuthCredential authCredential) {
          print("verification completed: auth credential");
        },
        verificationFailed: (AuthException authException) {
          print("verification failed: auth exception");
          print(authException.message);
        },
        codeSent: (String verificationId, [int forceResendingToken]) {
          print("code sent verification id" + verificationId);
        },
        codeAutoRetrievalTimeout: (String verificationId) {
          print("auto time" + verificationId);
        });
  }
}

但我不能在verifyPhoneNumber回调中使用 yield。问题是如何在回调函数中产生不同的状态?

4

2 回答 2

3

您可以从回调中添加事件。例如,在 中verificationCompleted,您可以执行以下操作:

verificationCompleted: (AuthCredential authCredential) {
    print("verification completed: auth credential");
    add(AuthCompleted());
},

您可以在以下时间处理AuthCompleted()事件mapEventToState

@override
  Stream<AuthState> mapEventToState(
    AuthEvent event,
  ) async* {
    if (event is VerifyPhone) {
      yield* _mapVerifyPhoneToState(event);
    }
    if (event is AuthCompleted){
      //Here you can use yield and whathever you want
    }
  }
于 2020-01-08T14:43:05.817 回答
0

电话验证块

class PhoneAuthenticationBloc
        extends Bloc<PhoneAuthenticationEvent, PhoneAuthenticationState> {
      final AuthRepository _authRepository;
      final AuthBloc _authBloc;      
        
           
            @override
          Stream<PhoneAuthenticationState> mapEventToState(
            PhoneAuthenticationEvent event,
          ) async* {
            if (event is PhoneLoadingEvent) {
              yield PhoneLoadingState();
            } else if (event is PhoneVerificationFailedEvent) {
              yield PhoneOTPFailureState(event.failure);
            } else if (event is PhoneSmsCodeSentEvent) {
              yield PhoneSmsCodeSentState(
                  verificationId: event.verificationId, resendCode: event.resendId);
            } else if (event is PhoneVerifiedOtpEvent) {
              yield* _mapToVerifyOtp(event.smsCode, event.verificationId);
            }
          }
             void verifyPhoneNumber(String phoneNumber) async {
                try {
                  add(PhoneLoadingEvent());
                  await _authRepository.verifyPhoneNumber(phoneNumber,
                      onRetrieval: (String retrievalCode) {
                    print("Time Out Retrieval Code: $retrievalCode");
                  }, onFailed: (Failure f) {
                    print("OnFailed: ${f.message}");
            
                    add(PhoneVerificationFailedEvent(f));
                  }, onCompleted: (Map<String, dynamic> data) {
                    print("verificationCompleted: $data");
                  }, onCodeSent: (String verificationId, int resendCode) {
                    print("verificationId:$verificationId & resendCode: $resendCode");
                    add(PhoneSmsCodeSentEvent(
                        verificationId: verificationId, resendId: resendCode));
                  });
                } catch (e) {
                  add(PhoneVerificationFailedEvent(Failure(message: e.toString())));
                }
              }}

用户界面屏幕

builder: (context, state) {
        return AppButton(
          isLoading: state is PhoneLoadingState,
          onPressed: () async {
            if (_formKey.currentState.validate()) {
              BlocProvider.of<PhoneAuthenticationBloc>(context)
                  .verifyPhoneNumber(_phoneController.text);
            }
          },
          title: "Continue",
          textColor: Colors.white,
        );
      }
于 2021-07-30T08:41:10.360 回答