【问题标题】:Cannot convert Future<String> to String and use in Dart (Flutter)无法将 Future<String> 转换为 String 并在 Dart (Flutter) 中使用
【发布时间】:2020-11-17 19:18:45
【问题描述】:

我尝试在我的移动应用中实施 Firebase 身份验证。 (我对此很陌生..)

我有以下代码第一次尝试创建用户:

class WpAuthService {
  FirebaseAuth _auth = FirebaseAuth.instance;

  Stream<WpUser> get wpUser {
    return _auth.authStateChanges().map((User firebaseUser) =>
        (firebaseUser != null) ? WpUser(uid: firebaseUser.uid) : null);
  }

  Future<String> createUserWithEmail(email, password) async {
    UserCredential userCredential;
    try {
      userCredential = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
    } on FirebaseAuthException catch (e) {
      print(e.code + " - " + e.message);
      return e.message;
    }

    return 'SUCCESS';
  }
}

在另一个文件中,我尝试调用createUserWithEmail 函数,如下所示:

class SignupForm extends StatefulWidget {
  @override
  _SignupFormState createState() => _SignupFormState();
}

class _SignupFormState extends State<SignupForm> {
  final _formKey = GlobalKey<FormState>();
  var _userEmail = "";
  var _userPassword = "";

  String _opResult;

  void _trySubmit() {
    final isValid = _formKey.currentState.validate();
    FocusScope.of(context).unfocus();

    if (isValid) {
      _formKey.currentState.save();

      WpAuthService()
          .createUserWithEmail(_userEmail, _userPassword)
          .then((value) {
        setState(() {
          _opResult = value;
        });
      });

      print('MESSAGE:');
      print(_opResult);
      if (_opResult != 'SUCCESS') {
        Scaffold.of(context).showSnackBar(
          SnackBar(
            content: Text(_opResult),
            backgroundColor: Theme.of(context).errorColor,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Card(
        margin: EdgeInsets.all(20),
        child: SingleChildScrollView(
          child: Padding(
            padding: EdgeInsets.all(16),
            child: Form(
              key: _formKey,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  TextFormField(
                    key: ValueKey('email'),
                    validator: (value) {
                      if (value.isEmpty || !value.contains('@')) {
                        return 'Please enter a valid email address.';
                      }
                      return null;
                    },
                    keyboardType: TextInputType.emailAddress,
                    decoration: InputDecoration(labelText: 'Email address'),
                    onSaved: (value) {
                      _userEmail = value;
                    },
                  ),
                  TextFormField(
                    key: ValueKey('password'),
                    validator: (value) {
                      if (value.isEmpty || value.length < 7) {
                        return 'Password must be at least 7 characters long.';
                      }
                      return null;
                    },
                    decoration: InputDecoration(labelText: 'Password'),
                    obscureText: true,
                    onSaved: (value) {
                      _userPassword = value;
                    },
                  ),
                  SizedBox(height: 12),
                  RaisedButton(
                    child: Text('Sign up',
                        style: Theme.of(context).textTheme.headline6),
                    onPressed: _trySubmit,
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

当我运行上面的代码时,它会打印出以下内容:

I/flutter ( 4032): MESSAGE:
I/flutter ( 4032): null

════════ Exception caught by gesture ═══════════════════════════════════════════
The following assertion was thrown while handling a gesture:
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 370 pos 10: 'data != null'

查看其他一些示例,我希望我的实现能够正常工作,但似乎有些错误。如何使用createUserWithEmail 函数的返回值作为字符串?

【问题讨论】:

  • 初始化String _opResult = "";有帮助吗?
  • @JoyTerence,请看下面我的回答。我的主要问题是无法将返回值设置为 _opResult 变量。 _opResult 的初始值实际上似乎不是问题。您的 cmets 非常受欢迎。
  • 您是仅在抛出异常时才遇到此问题,还是在“成功”的情况下才遇到此问题?
  • 只是一个补充,替代解决方案可能是使用FutureBuilder
  • 在按照我的回答更新代码之前,我在这两种情况下都遇到了问题,无论函数返回什么(成功或错误)。

标签: firebase flutter dart firebase-authentication


【解决方案1】:

默认情况下,您的 _opResult 变量是 null 并且您将其传递给抛出该断言的 Snackbar 的 Text 小部件。 您需要先等待响应返回,或者将代码更改为在 then 方法内。

void _trySubmit() {
    final isValid = _formKey.currentState.validate();
    FocusScope.of(context).unfocus();

    if (isValid) {
      _formKey.currentState.save();

      WpAuthService()
          .createUserWithEmail(_userEmail, _userPassword)
          .then((value) {

        setState(() {
          _opResult = value;
        });

        print('MESSAGE:');
        print(_opResult);
        if (_opResult != 'SUCCESS') {
          Scaffold.of(context).showSnackBar(
            SnackBar(
              content: Text(_opResult),
              backgroundColor: Theme.of(context).errorColor,
            ),
          );
        }
      });

    }
  }

【讨论】:

  • 感谢您的回答。除了我单独编写的解决方案之外,我还更改了代码并通过在我的 WpAuthService().createUserWithEmail 函数调用前面放置等待来使 _trySubmit 函数异步。通过这种方式,我想我可以确保等待响应。
【解决方案2】:

您的 _opResult 为空。它不等于“成功”。您正在尝试将其设置为 Text() 小部件。文本小部件需要一个字符串参数,而不是 null。

您可以在初始化 _opResult 时设置默认字符串。像这样:

  String _opResult = "";


  print('MESSAGE:');
  print(_opResult);
  if (_opResult != 'SUCCESS') {
    Scaffold.of(context).showSnackBar(
      SnackBar(
        content: Text(_opResult),
        backgroundColor: Theme.of(context).errorColor,
      ),
    );
  }

【讨论】:

    【解决方案3】:

    解决了。

    createUserWithEmail 函数中,我返回的字符串值如下:

    return e.message;
    return 'SUCCESS';
    

    我更新了它,现在函数返回如下所述:

    return Future.value(e.message);
    return Future.value('SUCCESS');
    

    其他一切都是一样的,而且有效。

    但是我看到了其他一些例子,人们只是从他们的函数中返回字符串值。我的问题已解决,但这种行为真的可以预期吗?非常欢迎您来教育我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-26
      • 2022-06-15
      • 2020-05-20
      • 2015-08-15
      • 2021-04-28
      相关资源
      最近更新 更多