1 year ago

#275354

test-img

Florian Leeser

How to solve Flutter: Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe

I am trying to send an E-Mail to the user for verifying his/her account after signing up. On top of that I am automatically navigating to a new screen whenever a user is signed in.

This is the error that I get:

E/flutter ( 8107): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter ( 8107): At this point the state of the widget's element tree is no longer stable.
E/flutter ( 8107): 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 ( 8107): #0      Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:4153:9)
E/flutter ( 8107): #1      Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:4167:6)
E/flutter ( 8107): #2      Element.getElementForInheritedWidgetOfExactType (package:flutter/src/widgets/framework.dart:4193:12)
E/flutter ( 8107): #3      ProviderScope.containerOf (package:flutter_riverpod/src/framework.dart:97:12)
E/flutter ( 8107): #4      ConsumerStatefulElement.read (package:flutter_riverpod/src/consumer.dart:487:26)
E/flutter ( 8107): #5      SignUpScreen.build.<anonymous closure> (package:scial/screens/sign_up/sign_up_screen.dart:97:31)
E/flutter ( 8107): <asynchronous suspension>

This is a code snippet from signup:

await auth.createUserWithEmailAndPassword(email: email, password: password);
await dynamicLinksService.sendEmailVerificationEmail(context, user: auth.currentUser!);

This is the stream that checks if there is a current user:

Stream<UserMode> get currentUserMode => auth.authStateChanges().map((User? user) => user != null ? user.emailVerified ? UserMode.isEmailVerified : UserMode.isAvailable : UserMode.none);

This is the important snippet of my GoRouter:

final GoRouter router = GoRouter(
  refreshListenable: isAuthenticatedListenable,
  redirect: (GoRouterState state) {
    UserMode? userMode = isAuthenticatedListenable.value;

    bool isBase = state.subloc == '/';
    bool isAuthenticating = state.subloc == '/signin' || state.subloc == '/signup';
    bool isEmailVerifying = state.subloc == '/verify';

    if (userMode == null && !isBase) return '/';
    if (userMode == UserMode.none && !isAuthenticating) return '/signin';
    if (userMode == UserMode.isAvailable && !isEmailVerifying) return '/verify';

    return null;
  },
  routes: <GoRoute>[
    GoRoute(
      path: '/',
      builder: (BuildContext context, GoRouterState state) {
        return Container(color: Colors.blue);
      }
    ),
    GoRoute(
      path: '/signin',
      name: 'signin',
      builder: (BuildContext context, GoRouterState state) {
        return const SignInScreen();
      }
    ),
    GoRoute(
      path: '/signup',
      name: 'signup',
      builder: (BuildContext context, GoRouterState state) {
        return const SignUpScreen();
      }
    ),
    GoRoute(
      path: '/verify',
      name: 'verify',
      builder: (BuildContext context, GoRouterState state) {
        return const VerifyScreen();
      }
    )
  ]
);

This means right after signing up, the App shows a new screen and while doing that or maybe even after that, the sendVerificationLink action is called. I think this is where the error occurs, but I can not figure out how to fix this in a clean way.

If someone could provide a working code example and explanation, that would be great!

firebase

flutter

dart

gorouter

0 Answers

Your Answer

Accepted video resources