Home > Net >  Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe
Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe

Time:01-24

The code below worked well previously but unsure how this error is coming up.

class LoginScreen extends StatelessWidget {
//  const LoginScreen({Key key}) : super(key: key);
  static const String idScreen = "login";
  final TextEditingController nameTextEditingController =
      TextEditingController();
  final TextEditingController phoneTextEditingController =
      TextEditingController();
  final TextEditingController passwordTextEditingController =
      TextEditingController();
  final TextEditingController emailTextEditingController =
      TextEditingController();
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              SizedBox(
                height: 35.0,
              ),
              Image(
                image: AssetImage("images/images/logo.png"),
                width: 390.0,
                height: 350.0,
                alignment: Alignment.center,
              ),
              SizedBox(
                height: 1.0,
              ),
              Text(
                "Login as Driver",
                style: TextStyle(fontSize: 24, fontFamily: "Brand Bold"),
                textAlign: TextAlign.center,
              ),
              Padding(
                padding: EdgeInsets.all(20.0),
                child: Column(
                  children: [
                    SizedBox(
                      height: 1.0,
                    ),
                    TextField(
                      controller: emailTextEditingController,
                      keyboardType: TextInputType.emailAddress,
                      decoration: InputDecoration(
                        labelText: "Email",
                        labelStyle: TextStyle(
                          fontSize: 18.0,
                        ),
                      ),
                      style: TextStyle(fontSize: 18.0),
                    ),
                    SizedBox(
                      height: 1.0,
                    ),
                    TextField(
                      controller: passwordTextEditingController,
                      obscureText: true,
                      decoration: InputDecoration(
                        labelText: "Password",
                        labelStyle: TextStyle(
                          fontSize: 18.0,
                        ),
                      ),
                      style: TextStyle(fontSize: 14.0),
                    ),
                    SizedBox(height: 10.0),
                    ElevatedButton(
                      //color: Colors.pink[200],
                      //textColor: Colors.white,
                      child: Container(
                        height: 50.0,
                        child: Center(
                          child: Center(
                            child: Text(
                              "Login",
                              style: TextStyle(
                                  fontSize: 18.0, fontFamily: "Brand-Bold"),
                            ),
                          ),
                        ),
                      ),
                      //shape: new RoundedRectangleBorder(
                      //   borderRadius: new BorderRadius.circular(24.0)),
                      onPressed: () {
                        if (!emailTextEditingController.text.contains("@")) {
                          displayToastMessage(
                              "Email address is not valid", context);
                        } else if (passwordTextEditingController.text.isEmpty) {
                          displayToastMessage("password is not valid", context);
                        } else {
                          loginUser(context);
                        }
                      },
                    ),
                  ],
                ),
              ),
              TextButton(
                onPressed: () {
                  Navigator.pushNamedAndRemoveUntil(
                      context, RegistrationScreen.idScreen, (route) => false);
                },
                child: Text(
                  "Account not found, Please register",
                  style: TextStyle(color: Colors.black),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void loginUser(BuildContext context) async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return ProgressDialog(
            message: "Authenticating, Please wait...",
          );
        });
    final User? firebaseUser = (await _firebaseAuth
            .signInWithEmailAndPassword(
                email: emailTextEditingController.text,
                password: passwordTextEditingController.text)
            .catchError((errMsg) {
      Navigator.pop(context);
      displayToastMessage("Error: "   errMsg.toString(), context);
    }))
        .user;

    if (firebaseUser != null) {
      driversRef.child(firebaseUser.uid).once().then((DatabaseEvent event) {
        if (event.snapshot.value != null) {
          Navigator.pushNamedAndRemoveUntil(
              context, MainScreen.idScreen, (route) => false);
          displayToastMessage("You are logged in", context);
        } else {
          Navigator.pop(context);
          _firebaseAuth.signOut();
          displayToastMessage(
              "No record exists for this user, please create a new account",
              context);
        }
      });
    } else {
      Navigator.pop(context);
      displayToastMessage("An error occured, cannot sign in", context);
    }

 
  }
}

I read other similar question but using the Navigator.pushNamedAndRemoveUntil in the dispose method. unsure how to do it.

The error points out at

          Navigator.pushNamedAndRemoveUntil( //here
              context, MainScreen.idScreen, (route) => false);
          displayToastMessage("You are logged in", context);
        } else {

CodePudding user response:

You are calling the displayToastMessage with the context of a widget that has been removed from the tree and its context is no longer valid. For example here

Navigator.pushNamedAndRemoveUntil(context, MainScreen.idScreen, (route) => false);
displayToastMessage("You are logged in", context);

You are navigating to other screen and removing the current widget from the tree. In the next line you are calling displayToastMessage using the context of current widget which is already deactivated. The same problem occurs when using the Navigator.pop before displayToastMessage.

A solution is to call the displayToastMessage before navigating.

displayToastMessage("You are logged in", context);
Navigator.pushNamedAndRemoveUntil(context, MainScreen.idScreen, (route) => false);

Alternatively, you can call the displayToastMessage from the widget that you are navigating to.

  • Related