簡體   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