【问题标题】:Flutter bloc and Firebase phone authFlutter bloc 和 Firebase 电话身份验证
【发布时间】:2019-08-05 14:07:43
【问题描述】:

enter code here我正在尝试创建一个使用 Firebase 电话身份验证的 LoginBloc。我为phoneNumber、smsCode 和verificationId 创建了一个StreamController。我想借助 Bloc 模式在 VerificationNumber() 方法中动态添加它们的值。这是 verifyNumber() 中的 LoginBloc:

class LoginBloc extends Object with AuthValidator implements BlocBase {

  String _phone;
  String _sms;
  String _verifId;

  StreamController<String> _phoneController=StreamController<String>.broadcast();

  //Sink<String> get _addPhone=>_phoneController.sink;
  Stream<String> get getPhone=>_phoneController.stream.transform(validatePhone);

  StreamController<String> _codeController=StreamController<String>.broadcast();

  Stream<bool> get registerValid => Observable.combineLatest2(getPhone,getPhone
          ,(e, p) =>true);

  //Sink<String> get _addCode=>_phoneController.sink;
  Stream<String> get getCode=>_phoneController.stream.transform(validatePhone);
  Function(String) get onPhoneChanged => _phoneController.sink.add;

  StreamController<String> _verificationIdController=StreamController<String>.broadcast();

  Sink<String> get _addVerification=>_verificationIdController.sink;
  Stream<String> get getVerification=>_verificationIdController.stream;

  @override
  void dispose() {
    _phoneController.close();
    _codeController.close();
    _verificationIdController.close();
  }

  Future<void> verifyPhone(String phone, String verifId,String sms) async {

    _phone=phone;
    _sms=sms;
    _verifId=verifId;

    final PhoneCodeAutoRetrievalTimeout autoRetrieve=(String verId) {
      _verifId=verId;
      _addVerification.add(_verifId);
    };

    final PhoneCodeSent smsCodeSent=(String verId,[int forceCodeRetrieve]) {
      _verifId=verId;
      _addVerification.add(_verifId);
    };

    final PhoneVerificationCompleted phoneVerificationCompleted=(FirebaseUser user) {
      print("User $user");
    };

    final PhoneVerificationFailed phoneVerificationFailed=(AuthException exception) {
      print("Error $exception");
    };

    await FirebaseAuth.instance.verifyPhoneNumber(
        phoneNumber: _phone,
        timeout: Duration(minutes: 1),
        verificationCompleted: phoneVerificationCompleted,
        verificationFailed: phoneVerificationFailed,
        codeSent: smsCodeSent,
        codeAutoRetrievalTimeout: autoRetrieve);
  }
}

LoginBloc loginBloc=LoginBloc();

【问题讨论】:

    标签: dart flutter firebase-authentication


    【解决方案1】:

    我现在有一个工作解决方案: 这是 login_bloc:

    import 'dart:async';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:flutter/material.dart';
    import 'package:phone_auth_bloc/services/auth/authentification.dart';
    import 'package:rxdart/rxdart.dart';
    import 'package:bloc_pattern/bloc_pattern.dart';
    
    class LoginBloc implements BlocBase {
      final Authentification _authentification = new Authentification();
    
    
      final _phoneControler = new BehaviorSubject<String>();
      Observable<String> get phoneStream => _phoneControler.stream;
      Sink<String> get phoneEvent => _phoneControler.sink;
    
      final _smsControler = new BehaviorSubject<String>();
      Observable<String> get smsStream => _phoneControler.stream;
      Sink<String> get smsEvent => _phoneControler.sink;
    
      var _controllerLoading = new BehaviorSubject<bool>(seedValue: false);
    
      Stream<bool> get outLoading => _controllerLoading.stream;
    
      final BuildContext context;
      LoginBloc(this.context);
    
       onClickPhone() async {
        print(_phoneControler.value);
        _controllerLoading.add(!_controllerLoading.value);
    
            await _authentification.verifyPhoneNumber(_phoneControler.value);
        _controllerLoading.add(!_controllerLoading.value);
    
    
      }
    
      Future<bool> onClickSms() async {
        print(_phoneControler.value);
    
        _controllerLoading.add(!_controllerLoading.value);
        bool isAuth = await _authentification.signWithPhone(
            _authentification?.verificationId, _smsControler.value);
        _controllerLoading.add(!_controllerLoading.value);
        print(isAuth);
        return isAuth;
      }
    
      @override
      void dispose() {
        _controllerLoading?.close();
        _phoneControler?.close();
        _smsControler?.close();
      }
    }
    

    和班级女巫交流:

    class Authentification{
      final _firebaseAuth= FirebaseAuth.instance;
       String verificationId;
    
      Future<bool> signWithPhone(String verifiId,String smsCode) async{
        verificationId=verifiId;
        print(verificationId);
       final resultLogin=await _firebaseAuth.signInWithPhoneNumber(verificationId: verificationId, smsCode: smsCode);
       if(resultLogin?.uid!=null){
          return true;
       }else{
         return false;
       }
      }
    
      Future verifyPhoneNumber(String phone)async{
        await _firebaseAuth.verifyPhoneNumber(
            phoneNumber: phone,
            timeout: Duration(seconds: 30),
            verificationCompleted: (FirebaseUser user){
              print("User: "+user?.uid);
            },
            verificationFailed: (AuthException authException){
              print("exception: $authException");
            },
            codeSent: (String verifId,[int forceSent]){
              print("verificannId: $verifId");
              verificationId=verifId;
            },
            codeAutoRetrievalTimeout: (String timeOut){
              print("Time out: "+timeOut);
            });
      }
    }
    

    之后,您可以在 Ui 中调用 bloc,这是我的情况:

    class AuthForm extends StatefulWidget {
      @override
      _AuthFormState createState() => _AuthFormState();
    }
    
    class _AuthFormState extends State<AuthForm> {
      @override
      Widget build(BuildContext context) {
        LoginBloc loginBloc = BlocProvider.of<LoginBloc>(context);
    
        navigateTOnext(){
          loginBloc.onClickPhone().then((v){
    
    
              Navigator.of(context).pushReplacement(MaterialPageRoute(
                  builder: (BuildContext context) =>SmsCode()
              ),);
           // }else{
             // Center(child: CircularProgressIndicator());
            //}
          });
    
        }
    
        return Scaffold(
          appBar: AppBar(
            title: Text("formulaire d'authentification"),
          ),
          body: Container(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextField(
                  onChanged:loginBloc.phoneEvent.add,
                  onSubmitted:(String value) =>loginBloc.onClickPhone,
                  maxLength: 13,
                  keyboardType: TextInputType.phone,
                  decoration: InputDecoration(labelText: "Phone number"),
                ),
                RaisedButton(
                  onPressed: navigateTOnext,
    
                  child: Text("verifier"),
                ),
              ],
            ),
          ),
        );
    
    
      }
    

    【讨论】:

    • 很好的例子。 ui 中的这一行 builder: (BuildContext context) =&gt;SmsCode() 不清楚。你能澄清一下 SmsCode() 方法在做什么吗?
    • builder: (BuildContext context) =>SmsCode() 它只是一个等待短信发送到电话号码的另一个 UI 屏幕。
    猜你喜欢
    • 2020-02-21
    • 2021-06-10
    • 1970-01-01
    • 2020-04-26
    • 2021-02-12
    • 2020-01-23
    • 2021-06-27
    • 2021-05-03
    • 2019-03-05
    相关资源
    最近更新 更多