1

Error: [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. E/flutter ( 6342): At this point the state of the widget's element tree is no longer stable. E/flutter ( 6342): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method. E/flutter ( 6342): #0 Element._debugCheckStateIsActiveForAncestorLookup. (package:flutter/src/widgets/framework.dart:3864:9) E/flutter ( 6342): #1 Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3878:6) E/flutter ( 6342): #2 Element.findAncestorStateOfType (package:flutter/src/widgets/framework.dart:3926:12) E/flutter ( 6342): #3 Navigator.of (package:flutter/src/widgets/navigator.dart:2706:40) E/flutter ( 6342): #4 Navigator.pop (package:flutter/src/widgets/navigator.dart:2592:15) E/flutter ( 6342): #5 NotificationDialog.checkAvailabilityOfRide (package:drivers_app/Notifications/notificationDialog.dart:240:20) E/flutter ( 6342):

Snippet of my code:

 void checkAvailabilityOfRide(context) async {
    
      var rideRequestId = await rideRequestRef.once();
           ...
      var dataSnapShot2 =  await newRequestsRef.child(rideRequestId.value).once();
           ...
     Navigator.push(context, MaterialPageRoute(builder: (context)=> 
      NewRideScreen(rideDetails: rideDetails)));
         ...
   }

Updated Code:

 Widget build(BuildContext context) {
 return Dialog(
  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
  backgroundColor: Colors.transparent,
  elevation: 1.0,
  child: Container(
    margin: EdgeInsets.all(5.0),
    width: double.infinity,
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(5.0),
    ),
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        SizedBox(height: 30.0),
        Image.asset("images/taxi.png", width: 120.0,),
        SizedBox(height: 18.0,),
        Text("New Ride Request", style: TextStyle(fontFamily: "Brand-Bold", fontSize: 18.0,),),
        SizedBox(height: 30.0),
        Padding(
          padding: EdgeInsets.all(18.0),
          child: Column(
            children: [

              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Image.asset("images/pickicon.png", height: 16.0, width: 16.0,),
                  SizedBox(width: 20.0,),
                  Expanded(
                    child: Container(child: Text(rideDetails.pickup_address, style: TextStyle(fontSize: 18.0),)),
                  ),
                ],
              ),
              SizedBox(height: 15.0),

              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Image.asset("images/desticon.png", height: 16.0, width: 16.0,),
                  SizedBox(width: 20.0,),
                  Expanded(
                    child: Container(child: Text(rideDetails.dropOff_address, style: TextStyle(fontSize: 18.0),)),
                  )
                ],
              ),
              SizedBox(height: 15.0),

            ],
          ),
        ),

        SizedBox(height: 20.0),
        Divider(height: 2.0,color: Colors.black, thickness: 2.0,),
        SizedBox(height: 8.0),

        Padding(
          padding: EdgeInsets.all(20.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [

              FlatButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18.0),
                    side: BorderSide(color: Colors.red)),
                color: Colors.white,
                textColor: Colors.red,
                padding: EdgeInsets.all(8.0),
                onPressed: ()
                {
                  assetsAudioPlayer.stop();
                  Navigator.pop(context);
                },
                child: Text(
                  "Cancel".toUpperCase(),
                  style: TextStyle(
                    fontSize: 14.0,
                  ),
                ),
              ),

              SizedBox(width: 25.0),

              RaisedButton(
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(18.0),
                    side: BorderSide(color: Colors.green)),
                onPressed: ()
                {
                  assetsAudioPlayer.stop();
                  checkAvailabilityOfRide0(context);
                  checkAvailabilityOfRide(context);
                },

                color: Colors.green,
                textColor: Colors.white,
                child: Text("Accept".toUpperCase(),
                    style: TextStyle(fontSize: 14)),
              ),

            ],
          ),
        ),

        SizedBox(height: 10.0),
      ],
    ),
  ),
);

}

Future<void> checkAvailabilityOfRide(context) async {
   var rideRequestId = await rideRequestRef.once();
   Navigator.push(context);
   String theRideId = "";
   var dataSnapShot2 =  await newRequestsRef.child( rideRequestId.value).once();
   /*... process...*/

   if(theRideId == rideDetails.ride_request_id && r2canShare) {
   rideRequestRef.set("accepted");
   AssistantMethods.disableHomeTabLiveLocationUpdates();
   Navigator.push(context, MaterialPageRoute(builder: (context) => 
   NewRideScreen(rideDetails: rideDetails)));
 }
   else if(theRideId == 'cancelled') {
   displayToastMessage("Ride has been Cancelled.", context);
   }
   else if(theRideId == 'cancelled') {
   displayToastMessage("Ride has been time out.", context);
   }
   else if(r2canShare == false) {
   assetsAudioPlayer.stop();
   displayToastMessage("Rider 2 cannot shared ride, out of range.", context);
   }
   else {
   displayToastMessage("Ride not exists.", context);
   }

}

altered code:

  void checkAvailabilityOfRide(context)async{
    var dataSnapShot2 =  await newRequestsRef.child( (await 
      rideRequestRef.once()).value).once();
    Navigator.pop(context);
    String theRideId = "";
    /*... process...*/
Nin Yu
  • 21
  • 1
  • 8
  • Does this answer your question? [Flutter: Looking up a deactivated widget's ancestor is unsafe](https://stackoverflow.com/questions/61424636/flutter-looking-up-a-deactivated-widgets-ancestor-is-unsafe) – Patrick O'Hara May 11 '21 at 08:00
  • Still the same error, ....Looking up a deactivated widget's ancestor is unsafe. – Nin Yu May 11 '21 at 12:14
  • Please show the context where you call this function, providing enough code to reproduce the problem. – Patrick O'Hara May 11 '21 at 12:29
  • @PatrickO'Hara please see the code I added – Nin Yu May 11 '21 at 12:56
  • The edit does not show the context where the function is called, i.e. the `Widget` that calls it. – Patrick O'Hara May 11 '21 at 13:22
  • @PatrickO'Hara I added the widget, please see on the edit. – Nin Yu May 11 '21 at 15:04
  • OK, I have reproduced your code as a test, but it works OK. Note that I had to remove the line `Navigator.push(context);` which is invalid. I see from another answer that it was previously `Navigator.pop(context);` which causes the error that you first reported. So what code are you actually testing now? – Patrick O'Hara May 11 '21 at 16:47
  • @PatrickO'Hara I tried another way, and it somehow fix my problem, i combined the two await into one. And The navigator.pop already works. Originally it was two await , I queried twice in the database and must show the screen (Navigator.pop) but it fails, that's why i tried that technique and it works. See my altered Code. But the only thing is I cannot anymore access the RideRequestId, it would help in showing a toast message if the driver accepts or rejects the request of firstRider. But its okay atleast it could already navigate and pop the screen. – Nin Yu May 11 '21 at 17:58
  • I did some experiments, I will document them with some suggestions in an answer. You should be ok having multiple `await` statements before the `pop`, but do not have one after the `Navigator.pop` and before the `Navigator.push`. – Patrick O'Hara May 11 '21 at 18:09

2 Answers2

1

As the poster found (see comments on question), the error is caused by having an async await execute between the Navigator.pop and Navigator.push. I guess the await gives Flutter time to destroy the current screen before the push, which causes the exception on the push.

Note that Flutter provides various ways to pop and push at the same time, which avoid the chance of having intervening code: pushReplacement and pushReplacementNamed replace the current screen with a new one, and popAndPushNamed does the same with different animation.

Patrick O'Hara
  • 1,999
  • 1
  • 14
  • 18
  • thanks for your advice, i appreciate your effort in responding to my problems, I hope you could help me more in the future – Nin Yu May 11 '21 at 22:43
0

@Nin Yu, Past some days I got the same error I tried to fix using @Patrick answer, but that didn't work too sometimes. When I closely debug it I found I was calling method containing Navigator multiple times. So sometimes I got context and I pass safely to the next screen and some it throws an error. I would suggest debug method and check whether it occurence.

Ankit Tale
  • 1,924
  • 4
  • 17
  • 30