首页 > 解决方案 > 在不同的小部件之间共享回调

问题描述

我在我的 Flutter 应用程序中使用 FirebaseAuth。我正在尝试使用电话号码进行验证。这个想法是有一个页面供用户输入电话号码,另一个页面用于验证 SMS 代码。

这是我写的:

    FirebaseAuth.instance.verifyPhoneNumber(
      phoneNumber: phoneNumber,
      verificationCompleted:
          (PhoneAuthCredential credential) {},
      verificationFailed: (FirebaseAuthException e) {
        showError(
          context: context,
          firebaseAuthException: e,
        );
      },
      codeSent: (String verificationId, int resendToken) {
        Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => CodeVerification(
                verificationId: verificationId,
                resendToken: resendToken,
                authHandler: authHandler,
              )),
        );
      },
      codeAutoRetrievalTimeout: (String verificationId) {},
    );

但是当我将另一个小部件 ( CodeVerification) 推送到 时Navigator,我不知道第二个小部件中的verificationFailedverificationCompleted回调。

解决此问题的最佳方法是什么?

标签: flutterdart

解决方案


为什么需要将 Navigator 推送到另一条路线?您不能创建一个完全管理电话身份验证的单一路由吗?当回调触发您将其设置为 true时,我将创建一个有状态的小部件,bool以便显示/隐藏代码输入。codeSent

遵循未经测试的示例:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class PhoneAuthenticationScreen extends StatefulWidget {
  final String phoneNumber;

  const PhoneAuthenticationScreen({Key key, this.phoneNumber}) : super(key: key);

  @override
  _PhoneAuthenticationScreenState createState() => _PhoneAuthenticationScreenState();
}

class _PhoneAuthenticationScreenState extends State<PhoneAuthenticationScreen> {
  final _codeTextFieldController = TextEditingController();
  bool showCodeInput = false;
  String verificationId;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          buildSendCodeButton(),
          buildCodeInput(),
        ],
      ),
    );
  }

  buildSendCodeButton() {
    return RaisedButton(
      child: Text("send code"),
      onPressed: () {
        FirebaseAuth.instance.verifyPhoneNumber(
          phoneNumber: widget.phoneNumber,
          verificationCompleted: (PhoneAuthCredential credential) {},
          verificationFailed: (FirebaseAuthException e) {},
          codeSent: (String verificationId, int resendToken) {
            setState(() {
              showCodeInput = true;
              verificationId = verificationId;
            });
          },
          codeAutoRetrievalTimeout: (String verificationId) {},
        );
      },
    );
  }

  buildCodeInput() {
    if (!showCodeInput) return Container();

    return Row(
      children: [
        TextField(
          controller: _codeTextFieldController,
        ),
        RaisedButton(
          child: Text("Submit"),
          onPressed: () async {
            final smsCode = _codeTextFieldController.text;
            PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);
            await FirebaseAuth.instance.signInWithCredential(phoneAuthCredential);
          },
        )
      ],
    );
  }
}

推荐阅读