lulupointu / vrouter

MIT License
202 stars 38 forks source link

Can't get this to work at all #106

Closed CripyIce closed 3 years ago

CripyIce commented 3 years ago

Hi there, Started using this library but I can't get it to work properly. I keep getting RangeError: Index out of range: no indices are valid: 0 error.

full log:

A message on the flutter/keyevent channel was discarded before it could be handled.
This happens when a plugin sends messages to the framework side before the framework has had an opportunity to register a listener. See the ChannelBuffers API documentation for details on how to configure the channel to expect more messages, or to expect messages to get discarded:
  https://api.flutter.dev/flutter/dart-ui/ChannelBuffers-class.html
WARNING: You tried to set the url strategy several time, this should never happen.
If a package that you use (other than VRouter) sets the url strategy, please use the other package.

======== Exception caught by widgets library =======================================================
The following IndexError was thrown building VRouter(state: VRouterState#33dbc):
RangeError: Index out of range: no indices are valid: 0

The relevant error-causing widget was: 
  VRouter file:///Users/eitanaflalo/FlutterProjects/diams/lib/main.dart:66:14
When the exception was thrown, this was the stack: 
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49   throw_
dart-sdk/lib/html/dart2js/html_dart2js.dart 17635:46                           _get]
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 180:42  _getBasePath
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 95:22   getPathAndQuery
packages/vrouter/src/core/vlocations.dart 22:48                                new
...
====================================================================================================

======== Exception caught by widgets library =======================================================
The following IndexError was thrown building VRouter(state: VRouterState#33dbc):
RangeError: Index out of range: no indices are valid: 0

The relevant error-causing widget was: 
  VRouter file:///Users/eitanaflalo/FlutterProjects/diams/lib/main.dart:66:14
When the exception was thrown, this was the stack: 
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49   throw_
dart-sdk/lib/html/dart2js/html_dart2js.dart 17635:46                           _get]
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 180:42  _getBasePath
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 95:22   getPathAndQuery
packages/vrouter/src/core/vlocations.dart 22:48                                new
...
====================================================================================================

======== Exception caught by widgets library =======================================================
The following IndexError was thrown building VRouter(state: VRouterState#33dbc):
RangeError: Index out of range: no indices are valid: 0

The relevant error-causing widget was: 
  VRouter file:///Users/eitanaflalo/FlutterProjects/diams/lib/main.dart:66:14
When the exception was thrown, this was the stack: 
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49   throw_
dart-sdk/lib/html/dart2js/html_dart2js.dart 17635:46                           _get]
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 180:42  _getBasePath
packages/vrouter/src/wrappers/browser_helpers/browser_helpers_web.dart 95:22   getPathAndQuery
packages/vrouter/src/core/vlocations.dart 22:48                                new
...
====================================================================================================

main.dart

import 'package:bot_toast/bot_toast.dart';
import 'package:mytestapp/app/config.dart';
import 'package:mytestapp/model/post.dart';
import 'package:mytestapp/remote/api_provider.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
import 'package:vrouter/vrouter.dart';

import 'ui/home/home.dart';
import 'ui/login/login.dart';
import 'model/provider_models.dart';
import 'model/user.dart';
import 'subscription/subscription_page.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  if (!kIsWeb) {
    if (kDebugMode) {
      await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(false);
    }

    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
  }

  await Hive.initFlutter();

  Hive.registerAdapter<User>(UserAdapter());
  Hive.registerAdapter<Post>(PostAdapter());

  await Hive.openBox("data");
  await Hive.openBox<User>("user");
  await Hive.openBox<Post>("posts");

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  static FirebaseAnalytics analytics = FirebaseAnalytics();
  static FirebaseAnalyticsObserver analyticsObserver =
      FirebaseAnalyticsObserver(analytics: analytics);

  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider<ApiProvider>(
          create: (_) => ApiProvider(_navigatorKey),
        ),
        ChangeNotifierProvider(
          create: (_) => HomeProviderModel(),
        ),
      ],
      child: VRouter(
        title: 'MyTestApp',
        navigatorKey: _navigatorKey,
        navigatorObservers: [analyticsObserver, BotToastNavigatorObserver()],
        builder: BotToastInit(),
        debugShowCheckedModeBanner: false,
        mode: VRouterModes.history,
        theme: ThemeData(
          primaryColor: PRIMARY_COLOR,
          accentColor: PRIMARY_COLOR,
          brightness: Brightness.light,
          primaryColorBrightness: Brightness.light,
          visualDensity: VisualDensity.adaptivePlatformDensity,
          textTheme: GoogleFonts.latoTextTheme(
            Theme.of(context).textTheme,
          ),
          elevatedButtonTheme: ElevatedButtonThemeData(
            style: ElevatedButton.styleFrom(
              primary: PRIMARY_COLOR,
            ),
          ),
          textButtonTheme: TextButtonThemeData(
            style: TextButton.styleFrom(
              padding:
                  const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
              primary: Colors.black,
            ),
          ),
          outlinedButtonTheme: OutlinedButtonThemeData(
            style: TextButton.styleFrom(
              padding:
                  const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0),
              primary: Colors.black,
            ),
          ),
          backgroundColor: Colors.white,
          scaffoldBackgroundColor: Colors.white,
          sliderTheme: SliderThemeData(
            showValueIndicator: ShowValueIndicator.always,
            activeTrackColor: PRIMARY_COLOR,
            thumbColor: PRIMARY_COLOR,
          ),
        ),
        initialUrl: "/",
        routes: [
          VWidget(
            path: "/",
            widget: SplashPage(),
          ),
          VWidget(
            path: "/login",
            widget: LoginPage(),
          ),
          VWidget(
            path: "/home",
            widget: HomePage(),
          ),
          VWidget(
            path: "/subscription",
            widget: SubscriptionPage(),
          ),
          VRouteRedirector(path: r":_(.+)", redirectTo: "/"),
        ],
      ),
    );
  }
}

class SplashPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => SplashPageState();
}

class SplashPageState extends State<SplashPage> {
  @override
  void initState() {
    super.initState();

    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark.copyWith(
      systemNavigationBarColor: Colors.white,
      systemNavigationBarIconBrightness: Brightness.dark,
      statusBarColor: Colors.transparent,
    ));

    final dataBox = Hive.box("data");
    final userBox = Hive.box<User>("user");

    Future.delayed(Duration(milliseconds: 500)).then((value) {
      final User user = userBox.isNotEmpty ? userBox.getAt(0) : null;
      final String apiToken = dataBox.get("api_token", defaultValue: null);

      if (apiToken == null || apiToken.isEmpty) {
        context.vRouter.pushReplacement("/login");
      } else {
        if (user == null && apiToken != null && apiToken.isNotEmpty) {
//          FlutterSecureStorage().deleteAll();
          context.vRouter.pushReplacement("/login");
        } else {
          Provider.of<ApiProvider>(context, listen: false)
              .getUserDetails()
              .then((_) => context.vRouter.pushReplacement("/home"));
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: PRIMARY_COLOR,
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(
              width: MediaQuery.of(context).size.width * 0.25,
              child: Image.asset("assets/icon/icon.png"),
            ),
            Text(
              "My Test App",
              style: Theme.of(context)
                  .textTheme
                  .headline4
                  .copyWith(color: Colors.white),
            ),
          ],
        ),
      ),
    );
  }
}

flutter doctor

[✓] Flutter (Channel stable, 2.2.2, on macOS 11.4 20F71 darwin-x64, locale en-IL)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.57.1)
[✓] Connected device (2 available)
    ! Error: Eitan’s iPhone is not connected. Xcode will continue when Eitan’s iPhone is connected. (code -13)

Thanks in advance!

lulupointu commented 3 years ago

VRouter.builder seems wrong. It is supposed to give you a context and a child and you must use the child.

CripyIce commented 3 years ago

@lulupointu Thanks for the fast response, but can you explain a bit more? What should I change in my code to make it work?

lulupointu commented 3 years ago

What is BotToastInit()?

lulupointu commented 3 years ago

You should replace it by (context, child) => BotToastInit(child: child) and return that child at some point.

CripyIce commented 3 years ago

I removed BotToastNavigatorObserver() from navigatorObservers and builder: BotToastInit(), completely, and still get an error:

Error: RangeError: Index out of range: no indices are valid: 0
    at Object.throw_ [as throw] (http://localhost:54077/dart_sdk.js:5348:11)
    at HTMLCollection.[dartx._get] (http://localhost:54077/dart_sdk.js:85475:70)
    at Function.pushReplacement (http://localhost:54077/packages/vrouter/src/widgets/vwidget_guard.dart.lib.js:7084:128)
    at vrouter_delegate.VRouterDelegate.new._updateUrl (http://localhost:54077/packages/vrouter/src/widgets/vwidget_guard.dart.lib.js:7714:48)
    at _updateUrl.next (<anonymous>)
    at http://localhost:54077/dart_sdk.js:39230:33
    at _RootZone.runUnary (http://localhost:54077/dart_sdk.js:39087:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:54077/dart_sdk.js:34073:29)
    at handleValueCallback (http://localhost:54077/dart_sdk.js:34633:49)
    at Function._propagateToListeners (http://localhost:54077/dart_sdk.js:34671:17)
    at _Future.new.[_completeWithValue] (http://localhost:54077/dart_sdk.js:34513:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:54077/dart_sdk.js:34536:35)
    at Object._microtaskLoop (http://localhost:54077/dart_sdk.js:39374:13)
    at _startMicrotaskLoop (http://localhost:54077/dart_sdk.js:39380:13)
    at http://localhost:54077/dart_sdk.js:34887:9
lulupointu commented 3 years ago

Even after stopping and starting again your app?

lulupointu commented 3 years ago

Also do you still have "WARNING: You tried to set the url strategy several time, this should never happen. If a package that you use (other than VRouter) sets the url strategy, please use the other package."?

CripyIce commented 3 years ago

Yes, even after stopping and starting my app again. And I still get this warning WARNING: You tried to set the url strategy several time, this should never happen. If a package that you use (other than VRouter) sets the url strategy, please use the other package. even after a fresh start of my app.

Note that on iOS it seems to work fine.

lulupointu commented 3 years ago

Could you try to remove everything possible until you don't get the error? Then share the code

CripyIce commented 3 years ago

Yes of course. I have another web project and it works there perfectly. I'm comparing the code to see what is causing the issue. I will post a comment of course with updates.

CripyIce commented 3 years ago

With the following code it works great on web, but I still can't find what is causing the issue - maybe you could help me understand. It seems that builder: BotToastInit() doesn't causes the issue. main.dart

import 'package:bot_toast/bot_toast.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'package:sdo_cms/remote/api_provider.dart';
import 'package:vrouter/vrouter.dart';

import 'app/config.dart';
import 'home.dart';
import 'login.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(App());
}

class App extends StatelessWidget {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initialization,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return MyApp();
        }

        return SizedBox.shrink();
      },
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<ApiProvider>(
      create: (_) => ApiProvider(),
      child: VRouter(
        title: "SDO CMS",
        builder: BotToastInit(),
        navigatorObservers: [BotToastNavigatorObserver()],
        // mode: VRouterModes.history,
        theme: ThemeData(
          primaryColor: PRIMARY_COLOR,
          accentColor: PRIMARY_COLOR,
          visualDensity: VisualDensity.adaptivePlatformDensity,
          elevatedButtonTheme: ElevatedButtonThemeData(
            style: ElevatedButton.styleFrom(
              primary: PRIMARY_COLOR,
            ),
          ),
          textButtonTheme: TextButtonThemeData(
            style: TextButton.styleFrom(primary: PRIMARY_COLOR),
          ),
          textTheme: GoogleFonts.quicksandTextTheme(
            Theme.of(context).textTheme,
          ),
        ),
        localizationsDelegates: [
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: [
          Locale("fr", "FR"),
        ],
        locale: Locale("fr", "FR"),
        initialUrl: "/",
        routes: [
          VWidget(
            path: "/",
            widget: SplashPage(),
          ),
          VWidget(
            path: "/login",
            widget: LoginPage(),
          ),
          VWidget(
            path: "/home",
            widget: HomePage(),
          ),
          VRouteRedirector(path: r":_(.+)", redirectTo: "/"),
        ],
        // initialRoute: "/",
        // routes: {
        //   "/": (context) => SplashPage(),
        //   "/login": (context) => LoginPage(),
        //   "/home": (context) => HomePage(),
        // },
        // onUnknownRoute: (RouteSettings settings) {
        //   return MaterialPageRoute<void>(
        //     settings: settings,
        //     builder: (BuildContext context) =>
        //         Scaffold(body: Center(child: Text("Not Found"))),
        //   );
        // },
      ),
    );
  }
}

class SplashPage extends StatefulWidget {
  @override
  _SplashPageState createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  FirebaseAuth _auth = FirebaseAuth.instance;

  @override
  void initState() {
    super.initState();

    Future.delayed(Duration(seconds: 2)).then((value) =>
        context.vRouter.push(_auth.currentUser == null ? "/login" : "/home"));
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
lulupointu commented 3 years ago

Oh I think I know !

Do you have the following in your index.html:

<base href="/">

It should be inside the <head> tag.

Tell me if this does the trick.

Also I will shit a fix for that in v1.2 so that it's no longer mandatory. However this version could not be here before a few days as I'm making some other changes

CripyIce commented 3 years ago

I didn't had this code <base href="/"> and after adding it in <head> tag it seems to work fine.

lulupointu commented 3 years ago

Feel free to close this then if everything is working. This won't be an issue even without the tag after v1.2 anyway