可空值和不可空值

Posted

技术标签:

【中文标题】可空值和不可空值【英文标题】:Nullable and non-nullable values 【发布时间】:2021-08-31 19:05:05 【问题描述】:

我正在使用 Flutter 和 Firebase 进行用户身份验证。

我遇到的问题是以下代码段:

import 'package:flutter/material.dart';

class AuthClass 

  final FirebaseAuth auth = FirebaseAuth.instance;

//Signing in a user
  Future<String> signIn(String email, String password) async 
    try 
      await auth.signInWithEmailAndPassword(
          email: email,
          password: password
      );
      return "Welcome!";
     on FirebaseAuthException catch (e) 
      if (e.code == 'user-not-found') 
        return 'No user found for that email.';
       else if (e.code == 'wrong-password') 
        return 'Wrong password provided for that user.';
      
    
  

我从中调用 signIn 函数的上下文就在这里:

import 'package:flutter_client_app/Provider/auth_provider.dart';
import 'package:flutter_client_app/Screens/home.dart';

class LoginPage extends StatefulWidget 
  @override
  _LoginPageState createState() => _LoginPageState();


class _LoginPageState extends State<LoginPage> 

  TextEditingController _email = TextEditingController();
  TextEditingController _password = TextEditingController();

  bool isLoading = false;
  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(title: Text("Login"),),

        body: isLoading == false ? Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              TextFormField(
                  controller: _email,
                  decoration: InputDecoration(
                      hintText: "Email"
                  )
              ),
              const SizedBox(height: 30,),

              TextFormField(
                  controller: _password,
                  decoration: InputDecoration(
                      hintText: "Password"
                  )
              ),

              FlatButton(     <=============================================================
                  color: Colors.blue,
                  onPressed: () 
                    print (_email.text);
                    print (_password.text);
                    setState(() 
                      isLoading = true;
                    );
                    AuthClass()
                        .signIn(
                          email: _email.text.trim(),
                          password: _password.text.trim())
                        .then((value) 
                      if (value == "Welcome!") 
                        setState(() 
                          isLoading = false;
                        );
                        Navigator.pushAndRemoveUntil(
                            context,
                            MaterialPageRoute(builder: (context) => HomePage()),
                                (route) => false);
                       else 
                        setState(() 
                          isLoading = false;
                        );
                        ScaffoldMessenger.of(context)
                            .showSnackBar(SnackBar(content: Text(value)));
                      
                    ); <==============================================================
                  ,
                  child: Text("Login to account")),
              SizedBox(
                height: 20,
              ),
              // GestureDetector(
              //   onTap: () 
              //     Navigator.pushAndRemoveUntil(
              //         context,
              //         MaterialPageRoute(
              //             builder: (context) => RegisterPage()), (route) => false);
              //   ,
              //   child: Text("Don't have an account? Register"),
              // ),
              //
              // const SizedBox(
              //   height: 10,
              // ),
              // GestureDetector(
              //   onTap: () 
              //     Navigator.pushAndRemoveUntil(
              //         context, MaterialPageRoute(builder: (context) => ResetPage()), (route) => false);
              //   ,
              //   child: Text("Forgot Password? reset"),
              //),
            ],
          ),
        ) : Center(
            child: CircularProgressIndicator(),
        )
    );
  

我得到的错误如下:

29:33:错误:参数“email”的值不能为“null”,因为它的类型为“String”,但隐含的默认值为“null”。

29:47:错误:参数“password”的值不能为“null”,因为它的类型为“String”,但隐含的默认值为“null”。

29:18:错误:必须返回非空值,因为返回类型“字符串”不允许为空。

我已经成功打印出记录在 TextFormField 中的值,但是当调用 signIn 异步函数时我的问题就出现了。

【问题讨论】:

【参考方案1】:

您正在使用null-safety 功能。您可以通过将 pubspec.yaml 中的 dart sdk 更改为 environment: sdk: "&gt;=2.7.0 &lt;3.0.0" 而不是 environment: sdk: "&gt;=2.12.0 &lt;3.0.0" 来禁用它,或者将您的课程设置为 null-safety。您还应该在catch 部分中返回elseif 的值。

import 'package:flutter/material.dart';

class AuthClass 

  final FirebaseAuth auth = FirebaseAuth.instance;

  //Signing in a user with nullable parameters
  Future<String> signIn(String? email, String? password) async 
    try 
      await auth.signInWithEmailAndPassword(
          email: email as String,
          password: password as String,
      );
      return "Welcome!";
     on FirebaseAuthException catch (e) 
      if (e.code == 'user-not-found') 
        return 'No user found for that email.';
       else if (e.code == 'wrong-password') 
        return 'Wrong password provided for that user.';
      
      else return "No Clear Error"
    
  
  //Signing in a user with default value parameters
  Future<String> signIn(String email = "", String password = "") async 
    try 
      await auth.signInWithEmailAndPassword(
          email: email,
          password: password,
      );
      return "Welcome!";
     on FirebaseAuthException catch (e) 
      if (e.code == 'user-not-found') 
        return 'No user found for that email.';
       else if (e.code == 'wrong-password') 
        return 'Wrong password provided for that user.';
      
      else return "No Clear Error"
    
  

【讨论】:

以上是关于可空值和不可空值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有可空值的吸气剂?

嵌套js代码中可空值的可空数组首先graphql

可空引用类型意外 CS8629 可空值类型可能为带有临时变量的空

C#进阶系列18 可空值类型

可空类型的 datagridview 组合框下拉列表中的空值

将可空值从 Activity 传递到 Fragment