android - Why is my flutter deeplink returning Page not found - Stack Overflow

EDIT: nl.fittestbody.Gainz: is not working as well.This doesn't return the NoPageFound screen,

EDIT: nl.fittestbody.Gainz:// is not working as well. This doesn't return the NoPageFound screen, but does give me back an error now as well:

Couldn't get a Routemaster object from the given context.
'package:routemaster/routemaster.dart':
Failed assertion: line 141 pos 7: 'widget != null'

I can't figure out why my deeplinking setup is not working. Im using routemaster and app_links packages.

nl.fittestbody.Gainz:// is working and gives me no error.

nl.fittestbody.Gainz://login is giving me an error and the NoPageFound screen.

I can't figure out why. Disabled native deeplinking with iOS in info.plist and Android in manifest.

My main file and my deeplinking service below. The '/' route is setup in my routes.

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // For preparing the key-value mem cache
  await KeyValueStorageBase.init();

  await Supabase.initialize(
    url: SupabaseConstants.apiUrl,
    anonKey: SupabaseConstants.apiAnon,
  );

  runApp(
    ProviderScope(
      child: TranslationProvider(
        child: const Gainz(),
      ) as Widget,
    ),
  );
}

class Gainz extends ConsumerStatefulWidget {
  const Gainz({super.key});

  @override
  ConsumerState<Gainz> createState() => _GainzState();
}

class _GainzState extends ConsumerState<Gainz> {
  late final AppLinks _appLinks;
  late final StreamSubscription<Uri>? _linkSubscription;

  @override
  void initState() {
    super.initState();
    ref.read(settingsControllerProvider.notifier).loadLocaleInMemory();
    _appLinks = AppLinks();
    _linkSubscription = _appLinks.uriLinkStream.listen((Uri uri) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        DeepLinkService.handleDeepLink(context, uri);
      });
    });
  }

  @override
  void dispose() {
    _linkSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final currentLocale = TranslationProvider.of(context);

    return ref.watch(authStateChangeProvider).when(
          data: (data) => MaterialApp.router(
            theme: ThemeStyle().lightTheme,
            debugShowCheckedModeBanner: false,
            title: 'Gainz',
            locale: currentLocale.flutterLocale,
            supportedLocales: AppLocaleUtils.supportedLocales,
            localizationsDelegates: const [
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            localeResolutionCallback: (locale, supportedLocales) {
              for (final supportedLocale in supportedLocales) {
                if (supportedLocale.languageCode == locale?.languageCode &&
                    supportedLocale.countryCode == locale?.countryCode) {
                  return supportedLocale;
                }
              }
              return supportedLocales.first;
            },
            builder: (context, child) {
              return OverlayManager(
                child: child ?? const SizedBox(),
              );
            },
            routerDelegate: RoutemasterDelegate(
              routesBuilder: (context) {
                if (data.session != null) {
                  return loggedInRoute;
                }
                return loggedOutRoute;
              },
            ),
            routeInformationParser: const RoutemasterParser(),
          ),
          error: (error, stackTrace) => ErrorText(error: error.toString()),
          loading: () => const Loader(),
        );
  }
}
class DeepLinkService {
  static void handleDeepLink(BuildContext context, Uri uri) {
    // Handle the redirect from Supabase verification
    if (uri.host == 'login') {
      Routemaster.of(context).replace('/');
      // Get the access token from the URL
      final accessToken = uri.queryParameters['access_token'];
      if (accessToken != null) {
        // Set the session with the access token
        Supabase.instance.client.auth.setSession(accessToken);
      }
    } else if (uri.host == 'email-verified') {
      // userModel is not updating after the redirect, is there an AuthChangeEvent?
      Routemaster.of(context).replace('/');
      return;
    } else {
      if (uri.host.isNotEmpty) {
        Routemaster.of(context).replace('/${uri.host}');
      } else {
        Routemaster.of(context).replace('/');
      }
    }
  }
}

part of my routes:

final loggedOutRoute = RouteMap(routes: {
  '/': (_) => const MaterialPage(child: AuthScreen()),
});

final loggedInRoute = RouteMap(
  onUnknownRoute: (path) => const MaterialPage(child: NotFoundPage()),
  routes: {
    '/': (_) => const MaterialPage(child: HomeScreen()),
    '/new-exercise': (_) => const MaterialPage(child: ExerciseUpdateScreen()),

EDIT: nl.fittestbody.Gainz:// is not working as well. This doesn't return the NoPageFound screen, but does give me back an error now as well:

Couldn't get a Routemaster object from the given context.
'package:routemaster/routemaster.dart':
Failed assertion: line 141 pos 7: 'widget != null'

I can't figure out why my deeplinking setup is not working. Im using routemaster and app_links packages.

nl.fittestbody.Gainz:// is working and gives me no error.

nl.fittestbody.Gainz://login is giving me an error and the NoPageFound screen.

I can't figure out why. Disabled native deeplinking with iOS in info.plist and Android in manifest.

My main file and my deeplinking service below. The '/' route is setup in my routes.

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // For preparing the key-value mem cache
  await KeyValueStorageBase.init();

  await Supabase.initialize(
    url: SupabaseConstants.apiUrl,
    anonKey: SupabaseConstants.apiAnon,
  );

  runApp(
    ProviderScope(
      child: TranslationProvider(
        child: const Gainz(),
      ) as Widget,
    ),
  );
}

class Gainz extends ConsumerStatefulWidget {
  const Gainz({super.key});

  @override
  ConsumerState<Gainz> createState() => _GainzState();
}

class _GainzState extends ConsumerState<Gainz> {
  late final AppLinks _appLinks;
  late final StreamSubscription<Uri>? _linkSubscription;

  @override
  void initState() {
    super.initState();
    ref.read(settingsControllerProvider.notifier).loadLocaleInMemory();
    _appLinks = AppLinks();
    _linkSubscription = _appLinks.uriLinkStream.listen((Uri uri) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        DeepLinkService.handleDeepLink(context, uri);
      });
    });
  }

  @override
  void dispose() {
    _linkSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final currentLocale = TranslationProvider.of(context);

    return ref.watch(authStateChangeProvider).when(
          data: (data) => MaterialApp.router(
            theme: ThemeStyle().lightTheme,
            debugShowCheckedModeBanner: false,
            title: 'Gainz',
            locale: currentLocale.flutterLocale,
            supportedLocales: AppLocaleUtils.supportedLocales,
            localizationsDelegates: const [
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            localeResolutionCallback: (locale, supportedLocales) {
              for (final supportedLocale in supportedLocales) {
                if (supportedLocale.languageCode == locale?.languageCode &&
                    supportedLocale.countryCode == locale?.countryCode) {
                  return supportedLocale;
                }
              }
              return supportedLocales.first;
            },
            builder: (context, child) {
              return OverlayManager(
                child: child ?? const SizedBox(),
              );
            },
            routerDelegate: RoutemasterDelegate(
              routesBuilder: (context) {
                if (data.session != null) {
                  return loggedInRoute;
                }
                return loggedOutRoute;
              },
            ),
            routeInformationParser: const RoutemasterParser(),
          ),
          error: (error, stackTrace) => ErrorText(error: error.toString()),
          loading: () => const Loader(),
        );
  }
}
class DeepLinkService {
  static void handleDeepLink(BuildContext context, Uri uri) {
    // Handle the redirect from Supabase verification
    if (uri.host == 'login') {
      Routemaster.of(context).replace('/');
      // Get the access token from the URL
      final accessToken = uri.queryParameters['access_token'];
      if (accessToken != null) {
        // Set the session with the access token
        Supabase.instance.client.auth.setSession(accessToken);
      }
    } else if (uri.host == 'email-verified') {
      // userModel is not updating after the redirect, is there an AuthChangeEvent?
      Routemaster.of(context).replace('/');
      return;
    } else {
      if (uri.host.isNotEmpty) {
        Routemaster.of(context).replace('/${uri.host}');
      } else {
        Routemaster.of(context).replace('/');
      }
    }
  }
}

part of my routes:

final loggedOutRoute = RouteMap(routes: {
  '/': (_) => const MaterialPage(child: AuthScreen()),
});

final loggedInRoute = RouteMap(
  onUnknownRoute: (path) => const MaterialPage(child: NotFoundPage()),
  routes: {
    '/': (_) => const MaterialPage(child: HomeScreen()),
    '/new-exercise': (_) => const MaterialPage(child: ExerciseUpdateScreen()),
Share Improve this question asked Mar 25 at 15:20 WesleyWesley 113 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Wrap the navigation call in a WidgetsBinding.instance.addPostFrameCallback

class DeepLinkService {
  static void handleDeepLink(BuildContext context, Uri uri) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (uri.host == 'login') {
        final accessToken = uri.queryParameters['access_token'];
        if (accessToken != null) {
          Supabase.instance.client.auth.setSession(accessToken);
        }
        Routemaster.of(context).replace('/');
      } else if (uri.host == 'email-verified') {
        Routemaster.of(context).replace('/');
      } else {
        if (uri.host.isNotEmpty) {
          Routemaster.of(context).replace('/${uri.host}');
        } else {
          Routemaster.of(context).replace('/');
        }
      }
    });
  }
}

This ensures that navigation occurs after the widget tree has built.

Ensure /login Exists in loggedOutRoute

final loggedOutRoute = RouteMap(routes: {
  '/': (_) => const MaterialPage(child: AuthScreen()),
  '/login': (_) => const MaterialPage(child: LoginScreen()), // Like this line
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744186360a4562223.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信