繁体   English   中英

如何将 Flutter Bloc 与 Firebase Phone Auth 结合使用

[英]How to use Flutter Bloc with Firebase Phone Auth

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

您可以从回调中添加事件。 例如,在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
    }
  }

电话认证块

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM