Flutter [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'BuildContext'

Flutter [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'BuildContext'

我正在尝试验证用户输入的用于注册的输入数据并收到此错误 [错误:flutter/lib/ui/ui_dart_state.cc(209)] 未处理的异常:类型 'Null' 不是类型 'BuildContext'

的子类型

这是我的代码:

class _LoginState extends State<Login> {
  final AuthService _auth = AuthService();
  final _formKey = GlobalKey<FormState>();

  TextEditingController _emailController = TextEditingController();
  TextEditingController _passwordController = TextEditingController();

  GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email']);
  late String _email, _password;
  String error = "";

  @override
  void initState() {
     super.initState();
  }

  bool _isObscure = true;
  @override
  Widget build(BuildContext context) {
    MediaQueryData mediaQueryData = MediaQuery.of(context);
    GoogleSignInAccount? user = _googleSignIn.currentUser;
    final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: !isKeyboard
          ? AppBar(
          titleSpacing: 12,
          leading: ModalRoute.of(context)?.canPop == true
              ? IconButton(
                  splashColor: Colors.transparent,
                  padding: const EdgeInsets.only(left: 30.0, bottom: 15.0),
                  icon: Icon(
                    Icons.arrow_back,
                    size: 35,
                  ),
                  onPressed: () => Navigator.of(context).pop(),
                  color: Colors.black,
                )
              : null,
          title: Image.asset('images/logo-name.png'),
          backgroundColor: new Color(0xffff),
          shadowColor: Colors.transparent,
          elevation: 0,
          toolbarHeight: 90.0,
        )
      : null,
  body: Center(
    child: Column(
      children: <Widget>[
        if (!isKeyboard)
          Container(
            child: RichText(
              textAlign: TextAlign.center,
              text: TextSpan(
                  text: "Made e-Groceries easier",
                  style: TextStyle(
                      fontSize: mediaQueryData.textScaleFactor /
                          mediaQueryData.textScaleFactor *
                          33,
                      fontFamily: 'Inter',
                      fontWeight: FontWeight.w600,
                      color: Colors.black)),
            ),
            width: mediaQueryData.size.width * 0.8,
          ),

        Container(
          child: Image(
              image: AssetImage("images/login.png"), fit: BoxFit.contain),
        ),

        Container(
            width: mediaQueryData.size.width * 0.85,
            child: Form(
                key: _formKey,
                child: SingleChildScrollView(
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                      TextFormField(
                          controller: _emailController,
                          validator: (input) {
                            if (input!.isEmpty)
                              return 'Pleas enter a valid Email';
                          },
                          decoration: InputDecoration(
                            focusedErrorBorder: OutlineInputBorder(
                              borderSide: BorderSide(color: Colors.red),
                            ),
                            errorBorder: OutlineInputBorder(
                              borderSide: BorderSide(color: Colors.red),
                            ),
                            errorStyle: TextStyle(height: 0.4),
                            contentPadding:
                                const EdgeInsets.symmetric(vertical: 20.0),
                            enabledBorder: OutlineInputBorder(
                                borderSide:
                                    BorderSide(color: Color(0xff2C6846))),
                            focusColor: Color(0xff2C6846),
                            focusedBorder: OutlineInputBorder(
                                borderSide: BorderSide(
                              color: Color(0xff2C6846),
                            )),
                            labelStyle: TextStyle(color: Color(0xff2C6846)),
                            labelText: "Email",
                            prefixIcon:
                                Icon(Icons.mail, color: Color(0xff2C6846)),
                          ),
                          onSaved: (input) => _email = input!),
                      SizedBox(height: 20),
                      TextFormField(
                          obscureText: _isObscure,
                          enableSuggestions: false,
                          autocorrect: false,
                          controller: _passwordController,
                          validator: (input) {
                            if (input!.length < 6)
                              return 'Provide minimum 6 character';
                          },
                          decoration: InputDecoration(
                              focusedErrorBorder: OutlineInputBorder(
                                borderSide: BorderSide(color: Colors.red),
                              ),
                              errorBorder: OutlineInputBorder(
                                borderSide: BorderSide(color: Colors.red),
                              ),
                              errorStyle: TextStyle(height: 0.4),
                              contentPadding: const EdgeInsets.symmetric(
                                  vertical: 20.0),
                              enabledBorder: OutlineInputBorder(
                                  borderSide:
                                      BorderSide(color: Color(0xff2C6846))),
                              focusColor: Color(0xff2C6846),
                              focusedBorder: OutlineInputBorder(
                                  borderSide:
                                      BorderSide(color: Color(0xff2C6846))),
                              labelStyle:
                                  TextStyle(color: Color(0xff2C6846)),
                              labelText: "Password",
                              suffixIcon: IconButton(
                                icon: Icon(
                                  _isObscure
                                      ? Icons.visibility
                                      : Icons.visibility_off,
                                  color: Color(0xff2C6846),
                                ),
                                onPressed: () {
                                  setState(() {
                                    _isObscure = !_isObscure;
                                  });
                                },
                              ),
                              prefixIcon: Icon(Icons.lock,
                                  color: Color(0xff2C6846))),
                          onSaved: (input) => _password = input!),
                    ])))),
        SizedBox(height: 20),
        ButtonTheme(
          buttonColor: Color(0xff2C6846),
          minWidth: mediaQueryData.size.width * 0.85,
          height: 60.0,
          child: RaisedButton(
              shape: RoundedRectangleBorder(
                borderRadius: new BorderRadius.circular(5.0),
              ),
              padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
              onPressed: () {
                if (_formKey.currentState!.validate()) {
                  signInUser();
                }
              },
              child: Text('Log In',
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 20.0,
                      fontWeight: FontWeight.w600))),
        )
      ],
    ),
  ),
);
}

  void signInUser() async {
    dynamic authResult = await _auth.loginUser(
        _emailController.text, _passwordController.text);
    if (authResult == null) {
      print("Sign in error. Could not be able to login");
    } else {
      _emailController.clear();
      _passwordController.clear();
      print('Sign in Successful');
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => HomePage()));
    }
  }
}

以上代码适用于AuthService.dart:

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  showError(Object errormessage) {
    var context;
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text('Note'),
            content: Text(errormessage.toString()),
            actions: <Widget>[
              FlatButton(
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                  child: Text('OK'))
            ],
          );
        });
  }

  Future loginUser(String email, String password) async {
    try {
      UserCredential result = await _auth.signInWithEmailAndPassword(
          email: email.toString(), password: password.toString());
      return result.user;
    } catch (e) {
      showError(e);
    }
  }
}

忽略乱七八糟的缩进,因为这是我第一次使用堆栈溢出。

问题可能来自

 Navigator.push(
          context, MaterialPageRoute(builder: (context) => HomePage()));

因此创建全局 BuildContext 变量并从构建方法初始化它。或者将上下文作为参数发送。喜欢

signInUser(BuildContext context)
...
showError(Object errormessage) {
    var context;
    showDialog(
        context: context,
...

showDialog 方法采用上下文参数,它使用此上下文查找有关您的应用程序的一些特别有用的信息,以便正确显示对话框,您没有传递正确的上下文。

你所做的是先声明一个变量context然后传递它,变量的值默认为null,所以你得到一个错误。

要解决此问题,您需要传递您的应用使用的真实上下文:

...
showError(BuildContext context, Object errormessage) {
    showDialog(
        context: context,
...

然后:

Future loginUser(BuildContext context, String email, String password) async {
    try {
      UserCredential result = await _auth.signInWithEmailAndPassword(
          email: email.toString(), password: password.toString());
      return result.user;
    } catch (e) {
      showError(context, e);
    }
  }

最后:

...
void signInUser() async {
    dynamic authResult = await _auth.loginUser(context, _emailController.text, _passwordController.text);
...

'Null' is not a subtype of type 'BuildContext' 错误意味着代码需要你的 BuildContext 但可能你给了 null。所以你应该使用 parts 检查 BuildContext。 当我查看您的代码时,我看到了错误行。 错误是您定义了上下文而不设置任何内容。所以它的值为空。 您应该传递带有参数的上下文。如果您传递上下文,您的问题将得到解决。

showError(Object errormessage) {
   var context;
   showDialog(
       context: context,