【问题标题】:How to use Flutter Bloc with Firebase Phone Auth如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用
【发布时间】:2020-04-26 02:23:20
【问题描述】:

我正在尝试使用 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。 问题是如何在回调函数内部产生不同的状态?

【问题讨论】:

    标签: flutter dart firebase-authentication flutter-bloc


    【解决方案1】:

    您可以从回调中添加事件。比如在verificationCompleted,你可以这样做:

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

    您可以在mapEventToState 上处理AuthCompleted() 事件:

    @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
        }
      }
    

    【讨论】:

      【解决方案2】:

      PhoneAuthenticationBloc

      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,
              );
            }
      

      【讨论】:

        猜你喜欢
        • 2019-08-05
        • 2020-02-21
        • 1970-01-01
        • 2021-06-14
        • 2021-06-10
        • 2020-03-26
        • 2019-03-05
        • 2020-05-11
        • 2021-02-12
        相关资源
        最近更新 更多