如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用
Posted
技术标签:
【中文标题】如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用【英文标题】:How to use Flutter Bloc with Firebase Phone Auth 【发布时间】: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。
问题是如何在回调函数内部产生不同的状态?
【问题讨论】:
【参考方案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,
);
【讨论】:
以上是关于如何将 Flutter Bloc 与 Firebase 电话身份验证一起使用的主要内容,如果未能解决你的问题,请参考以下文章