csells / go_router

The purpose of the go_router for Flutter is to use declarative routes to reduce complexity, regardless of the platform you're targeting (mobile, web, desktop), handling deep linking from Android, iOS and the web while still allowing an easy-to-use developer experience.
https://gorouter.dev
441 stars 96 forks source link

Loading routes after a Future makes deep linking does not work properly #208

Closed renanmgs closed 2 years ago

renanmgs commented 2 years ago

I need to load a json from an API using a future on startup BEFORE anything, even before the MaterialApp.router(), because i need to parse some urls and find some ids and redirect to some slugs.

When i open the app from a link, the app opens but it just go to the initialLocation, but if the app is alwready open or in second plane, the link just works!

I tried to use android:launchMode="singleTask" but the problem persists.

So the code is like this:

`

FutureBuilder( future: jsonFuture, ... if (snapshot.connectionState == ConnectionState.done) { return MaterialApp.router( ... GoRoute( name: "page_programa", path: "programa/:slug", pageBuilder: (context, state) { var programid = findProgramIdBySlug(state.params['slug']!); return MaterialPage( key: state.pageKey, child: ProgramScreen(programID: programid), );

` This findProgramIdBySlug function search on the json loaded in the future for an ID that the slug belongs, so in my URL things be like: mywebsite/program and not mywebsite/91589asf9851u987h1892yu58h7!3.

This makes the sharing of links user-friendly for us, but im not getting it to work whe the link need to open the app for the first time.

csells commented 2 years ago

Can you load your data in main() before starting the UI portion of your app?

renanmgs commented 2 years ago

Can you load your data in main() before starting the UI portion of your app?

I don't know why I didn't think about it sooner! I made the necessary changes but the app still goes to HomeScreen the first time it is launched.

Now i have the current structure:

 Future<void> main() async {

 //To increase memory cache size
   WidgetsFlutterBinding.ensureInitialized();
   if (kReleaseMode) {
     CustomImageCache();
   }
 //Removing appbar
   SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Colors.transparent));
 //Registring the font
   LicenseRegistry.addLicense(() async* {
     final license = await rootBundle.loadString('google_fonts/OFL.txt');
     yield LicenseEntryWithLineBreaks(['google_fonts'], license);
   });

  // for the Audio Service
   audioHandler = await AudioService.init(
     builder: () => AudioPlayerHandler(),
     config: AudioServiceConfig(
       androidNotificationChannelId: 'com.myapp.app.channel.audio',
       androidNotificationChannelName: 'NT Play',
       androidNotificationChannelDescription: 'NT Play',
       androidNotificationOngoing: true,
       notificationColor: Color(0xFF5a7ad1),
      androidNotificationIcon: 'mipmap/vazado',
     ),
   );
 //Getting the json from API
   await getJsonData();
   runApp(MyApp());
 }
renanmgs commented 2 years ago

The only thing i can think is that those futures are way too long:

When the app is in HOT state it just works.

image

csells commented 2 years ago

I don't know what the hot and cold states are.

renanmgs commented 2 years ago

COLD is when the app is not opened anywhere, Hot it is in background or in somewhere else.

csells commented 2 years ago

If I were you, I'd only do the things in main that are necessary for handling the deep link and leave the rest until after the app has loaded.