Sign In Error: type 'Null' is not a subtype of type '_StateDataWidget' in type cast

Viewed 145

Hello guys am trying to sign in to my flutter app but I keep on getting the error:

Sign In Error: type 'Null' is not a subtype of type '_StateDataWidget' in type cast,

I used the flutter authentication example in git here is the link: https://github.com/delay/flutter_firebase_auth_example,

Here is the code to my login form that contains the signIn function:

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
// ignore: import_of_legacy_library_into_null_safe
// import 'package:flushbar/flushbar.dart';
import '/components/authentication/util/auth.dart';
import '/components/authentication/util/validator.dart';
import '/components/authentication/util/state_widget.dart';
import '/components/authentication/authpages/accesspages/auth_loading_screen.dart';

class LoginForm extends StatefulWidget {
  const LoginForm({Key? key}) : super(key: key);

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

class _LoginFormState extends State<LoginForm> {
  final GlobalKey<FormState> _loginFormKey = GlobalKey<FormState>();
  late TextEditingController _emailController;
  late TextEditingController _passwordController;

  bool _autoValidate = false;
  bool _loadingVisible = false;

  @override
  void initState() {
    _emailController = new TextEditingController();
    _passwordController = new TextEditingController();
    super.initState();
  }

  bool _obscureText = true;
  // ignore: unused_element
  void _toggle() {
    setState(() {
      _obscureText = !_obscureText;
    });
  }

  Widget build(BuildContext context) {
    final emailField = TextFormField(
      controller: _emailController,
      keyboardType: TextInputType.emailAddress,
      validator: (value) => Validator.validateEmail(value!),
      // ignore: deprecated_member_use
      cursorColor: Theme.of(context).cursorColor,
      // initialValue: '@gmail.com',
      maxLength: 40,
      decoration: InputDecoration(
        filled: true,
        fillColor: Colors.white,
        labelText: 'Email:',
        labelStyle: TextStyle(color: Colors.red, fontSize: 20),
        helperText: 'Enter Your Email',
        helperStyle: TextStyle(color: Colors.black, fontSize: 15),
        enabledBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: Colors.red.shade600),
        ),
      ),
    );

    final passwordField = TextFormField(
      controller: _passwordController,
      obscureText: _obscureText,
      validator: (value) => Validator.validatePassword(value!),
      // ignore: deprecated_member_use
      cursorColor: Theme.of(context).cursorColor,
      maxLength: 40,
      decoration: InputDecoration(
        filled: true,
        fillColor: Colors.white,
        labelText: 'Password:',
        labelStyle: TextStyle(color: Colors.red, fontSize: 20),
        helperText: 'Enter Your Password',
        helperStyle: TextStyle(color: Colors.black, fontSize: 15),
        enabledBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: Colors.red.shade600),
        ),
        suffixIcon: IconButton(
          icon: Icon(
            _obscureText ? Icons.visibility : Icons.visibility_off,
          ),
          onPressed: _toggle,
          color: Colors.red,
        ),
      ),
    );

    final loginButton = ElevatedButton(
      child: Text(
        "login",
        style: TextStyle(
          fontWeight: FontWeight.w500,
          fontSize: 18.0,
          color: Colors.white,
        ),
      ),
      onPressed: () {
        _signIn(
            context: context,
            email: _emailController.text,
            password: _passwordController.text);
        // Navigator.pushNamed(context, '/Home');
      },
      style: ElevatedButton.styleFrom(
        primary: Colors.red,
        padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
      ),
    );

    final passwordResetLink = InkWell(
      child: Text(
        "Forgot Password?",
        style: TextStyle(
          color: Colors.grey.shade800,
          fontSize: 25,
          fontWeight: FontWeight.bold,
        ),
        textAlign: TextAlign.center,
      ),
      onTap: () {
        Future.delayed(Duration.zero, () {
          Navigator.pushNamed(context, '/Reset');
        });
      },
    );

    final registrationLink = InkWell(
      child: Text(
        "Registered? Sign Up",
        style: TextStyle(
          color: Colors.red,
          fontSize: 25,
          fontWeight: FontWeight.bold,
        ),
        textAlign: TextAlign.center,
      ),
      onTap: () {
        Future.delayed(Duration.zero, () {
          Navigator.pushNamed(context, '/Registration');
        });
      },
    );

    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: Container(
        height: MediaQuery.of(context).size.height,
        child: ListView(
          children: [
            Ink(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: AssetImage('assets/images/loginimage.jpg'),
                  fit: BoxFit.cover,
                ),
              ),
              child: Container(
                color: Colors.black.withOpacity(0.1),
                padding: const EdgeInsets.all(40.0),
                child: AuthLoadingScreen(
                  child: Form(
                    key: _loginFormKey,
                    // ignore: deprecated_member_use
                    autovalidate: _autoValidate,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          "LOGIN",
                          style: TextStyle(
                            color: Colors.red.shade600,
                            fontWeight: FontWeight.bold,
                            fontSize: 20.0,
                          ),
                          textAlign: TextAlign.center,
                        ),
                        const SizedBox(height: 10.0),
                        //EMAIL FIELD
                        emailField,
                        const SizedBox(
                          height: 10,
                        ),
                        //PASSWORD FIELD
                        passwordField,
                        const SizedBox(height: 20.0),
                        //LOGIN BUTTON
                        loginButton,
                        const SizedBox(height: 10.0),
                        //PASSWORD RESET LINK
                        passwordResetLink,
                        const SizedBox(height: 10.0),
                        //REGISTRATION LINK
                        registrationLink,
                        const SizedBox(height: 100.0),
                      ],
                    ),
                  ),
                  inAsyncCall: _loadingVisible,
                  offset: Offset.infinite,
                ),
              ),
            ),
            const SizedBox(height: 10.0),
            SizedBox(
                height: 50,
                width: 50,
                child: Image.asset('assets/icons/logoicon.jpeg')),
            const SizedBox(height: 10.0),
            Text(
              'Company',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontWeight: FontWeight.w500,
                fontSize: 20.0,
                color: Colors.red.shade900,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _changeLoadingVisible() async {
    setState(() {
      _loadingVisible = !_loadingVisible;
    });
  }

  void _signIn(
      {required String email,
      required String password,
      BuildContext? context}) async {
    if (_loginFormKey.currentState!.validate()) {
      try {
        SystemChannels.textInput.invokeMethod('TextInput.hide');
        await _changeLoadingVisible();
        //need await so it has chance to go through error if found.
        await StateWidget.of(this.context).logInUser(email, password);
        await Navigator.pushNamed(this.context, '/Home');
      } catch (error) {
        _changeLoadingVisible();
        print("Sign In Error: $error");
        // ignore: unused_local_variable
        String exception = Auth.getExceptionText(Exception(error));
        showDialog(
            context: this.context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Text("Auth Exception!"),
                content: Text("${exception} \n\n ${error}"),
                actions: <Widget>[
                  Row(
                    children: [
                      ElevatedButton(
                        child: Text("close"),
                        onPressed: () {
                          Navigator.of(context).pop();
                        },
                      ),
                    ],
                  )
                ],
              );
            });
      }
      ;
    } else {
      setState(() => _autoValidate = true);
    }
  }
}

Here is the code to the widget state file:

import 'auth.dart';
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '/models/state.dart';
import '/models/user_model.dart';
import '/models/user_settings.dart';


class StateWidget extends StatefulWidget {
  final StateModel state;
  final Widget child;

  StateWidget({
    required this.child,
    required this.state,
  });

  // Returns data of the nearest widget _StateDataWidget
  // in the widget tree.
  static _StateWidgetState of(BuildContext context) {
    return (context.dependOnInheritedWidgetOfExactType<_StateDataWidget>()
            as _StateDataWidget)
        .data;
  }

  @override
  _StateWidgetState createState() => new _StateWidgetState();
}

class _StateWidgetState extends State<StateWidget> {
  late StateModel state;
  //GoogleSignInAccount googleAccount;
  //final GoogleSignIn googleSignIn = new GoogleSignIn();

  @override
  void initState() {
    super.initState();
    if (widget.state != null) {
      state = widget.state;
    } else {
      state = new StateModel(firebaseUserAuth: this.state.firebaseUserAuth, user: this.state.user, userSettings: this.state.userSettings);
      initUser();
    }
  }

  Future<Null> initUser() async {
    //print('...initUser...');
    String firebaseUserAuth = await Auth.getCurrentFirebaseUser();
    UserModel? userModel = await Auth.getUserLocal();
    UserSettings? settings = await Auth.getSettingsLocal();
    setState(() {
      state.isLoading = false;
      state.firebaseUserAuth = firebaseUserAuth as User;
      state.user = userModel as User;
      state.userSettings = settings!;
    });
  }

  Future<void> logOutUser() async {
    await Auth.signOut();
    String firebaseUserAuth = await Auth.getCurrentFirebaseUser();
    setState(() {
      state.user = this.state.user;
      state.userSettings = this.state.userSettings;
      state.firebaseUserAuth = firebaseUserAuth as User;
    });
  }

  Future<void> logInUser(email, password) async {
    String userId = await Auth.signIn(email, password);
    UserModel? userModel = await Auth.getUserFirestore(userId);
    await Auth.storeUserLocal(userModel!);
    UserSettings? userSettings = await Auth.getSettingsFirestore(userId);
    await Auth.storeSettingsLocal(userSettings!);
    await initUser();
  }

  @override
  Widget build(BuildContext context) {
    return new _StateDataWidget(
      // key: null,
      data: this,
      child: widget.child,
    );
  }
}

class _StateDataWidget extends InheritedWidget {
  final _StateWidgetState data;

  _StateDataWidget({
    // Key? key,
    required Widget child,
    required this.data,
  }) : super(
    // key: key, 
    child: child
  );

  // Rebuild the widgets that inherit from this widget
  // on every rebuild of _StateDataWidget:
  @override
  bool updateShouldNotify(_StateDataWidget old) => true;
}

The rest of the files are on the link provided above from the git example since I haven't changed much form them.

0 Answers
Related