Flutter : Losing Provider State on Hot Reload - flutter

I'm using Provider v4.0.0 and when I hot reload the app I lose state from Provider class.
I know provider preserves it's state so obviously my code has some flaw. But I'm unable to find out what's wrong with my code.
Following is my main.dart file :
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scapperapp/provider/auth.dart';
import 'package:scapperapp/screens/authenticated.dart';
import 'package:scapperapp/screens/homepage.dart';
import 'package:scapperapp/screens/login.dart';
import 'package:scapperapp/screens/started.dart';
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [ChangeNotifierProvider(create: (context) => User())],
child: Consumer<User>(
builder: (context, User user, _) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepPurple,
primaryColor: Color(0xFF5B5A92),
accentColor: Color(0xFFadacdf),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: user.isAuthorised
? HomeScreen()
: FutureBuilder(
future: user.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? HomePage()
: HomePage(),
),
routes: {
SignupChoice.routeName: (context) => SignupChoice(),
LoginPage.routeName: (context) => LoginPage(),
HomeScreen.routeName: (context) => HomeScreen()
},
),
));
}
}
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}

Related

Flutter Conditional Route with Auto Route not working

i want to implement conditional routing with auto route package
isLoggedIn returns true but
autoroute redirects to login page,
how can i resolve this problem
import 'package:animated_splash_screen/animated_splash_screen.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:expense/config/routes/app_router.dart';
import 'package:expense/config/themes/theme_config.dart';
import 'package:expense/constants/assets_path_constants.dart';
import 'package:expense/constants/constants.dart';
import 'package:expense/core/auth/login/bloc/cubit/auth_cubit.dart';
import 'package:expense/core/auth/login/repository/mongodb/mongo_auth_repository.dart';
import 'package:expense/utils/services/lang/language_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'core/splash_screen.dart';
Future<void> main() async {
statusBar();
await _init();
runApp(
EasyLocalization(
supportedLocales: LanguageService.instance.supportedLocales,
path: AssetsPath.langAssetPath,
child: const Expense(),
),
);
}
void statusBar() {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: ColorConstants.backgroundColor,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
}
Future<void> _init() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
}
class Expense extends StatefulWidget {
const Expense({Key? key}) : super(key: key);
#override
State<Expense> createState() => _ExpenseState();
}
class _ExpenseState extends State<Expense> {
final _appRouter = AppRouter();
bool isLoggedIn = false;
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => AuthCubit(MongoAuthRepository()),
child: BlocConsumer<AuthCubit, AuthState>(
builder: (context, state) {
context.read<AuthCubit>().isValid();
return _buildMaterialApp(context, state);
},
listener: (context, state) {
if (state is TokenIsValid) {
isLoggedIn = state.isValid;
}
},
),
);
}
MaterialApp _buildMaterialApp(BuildContext context, AuthState state) {
print(isLoggedIn);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Gider',
// Tost Mesajı Init
builder: BotToastInit(),
theme: CustomTheme.primaryTheme,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: AnimatedSplashScreen(
splash: const SplashPage(),
animationDuration: const Duration(seconds: 2),
nextScreen: MaterialApp.router(
debugShowCheckedModeBanner: false,
theme: CustomTheme.primaryTheme,
routeInformationParser: _appRouter.defaultRouteParser(includePrefixMatches: true),
routerDelegate: _appRouter.delegate(
initialRoutes: [
if (isLoggedIn) HomeRoute(response: null) else const LoginRoute(),
],
),
),
),
);
}
}

Error: Could not find the correct Provider<AppStateNotifier> above this Consumer<AppStateNotifier> Widget

the following error occurs after I tried adding the provider feature to my app:
Error: Could not find the correct Provider above this Consumer Widget
This is my code for the ChangeNotifier:
import 'package:flutter/material.dart';
class AppStateNotifier extends ChangeNotifier {
bool isDarkMode = false;
void updateTheme(bool isDarkMode) {
this.isDarkMode = isDarkMode;
notifyListeners();
}
}
And there is my main class:
import 'package:wilson/src/config/theme_data.dart';
import 'package:wilson/src/routes/index.dart';
import 'package:wilson/src/utils/app_state_notifier.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Wilson extends StatelessWidget {
const Wilson({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Consumer<AppStateNotifier>(builder: (context, appState, child) {
return MaterialApp(
title: 'App-Name',
theme: ThemeConfig.lightTheme,
darkTheme: ThemeConfig.darkTheme,
themeMode: appState.isDarkMode ? ThemeMode.dark : ThemeMode.light,
onGenerateRoute: routes,
);
});
}
}
Maybe someone can help me with that, because I believe it's just a stupid little mistake.
You have to initialize this into your main.dart like this.
You can use multi provider if you have more than one provider files.
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: Doctorss()),
ChangeNotifierProvider.value(value: Categoriess()),
ChangeNotifierProvider.value(value: TopDoctors()),
ChangeNotifierProvider.value(value: Appointments()),
ChangeNotifierProvider.value(value: TopArticlesProvider()),
],
child: MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(color: Colors.blue[800]),
primaryColor: Colors.blue[800],
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.orange)),
debugShowCheckedModeBanner: false,
home: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapShot) {
if (snapShot.connectionState == ConnectionState.waiting) {
return const Start();
}
if (snapShot.hasData) {
return const homestate();
}
return const AuthScreen();
}),

The argument type 'MaterialApp Function(BuildContext, AppProvider, Widget)' can't be assigned to the parameter type. I am facing this error

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:resturant/providers/app_provider.dart';
import 'package:resturant/screens/splash.dart';
import 'package:resturant/util/const.dart';
import 'util/const.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AppProvider()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Consumer<AppProvider>(
builder: (BuildContext context, AppProvider appProvider, Widget child) {
return MaterialApp(
key: appProvider.key,
debugShowCheckedModeBanner: false,
navigatorKey: appProvider.navigatorKey,
title: Constants.appName,
theme: appProvider.theme,
darkTheme: Constants.darkTheme,
home: SplashScreen(),
);
},
);
}
}
I have checked all the code the only error i am facing is in the code up where Iam assingining builder. I have spend time to solve this but i can't.

Flutter 'No Overlay widget exists above EditableText' error when using Provider

Hey I've got a MultiProvider setup, and it's now throwing this error when tapping on a TextField whereas it didn't before I implemented the multi-provider:
No Overlay widget exists above EditableText
The error text does not give any helpful indication of what in the code is causing the issue, here is the code:
import 'package:***_mobile/Providers/user_auth_provider.dart';
import 'package:***_mobile/screens/browsing_page.dart';
import 'package:***_mobile/screens/film_details_page.dart';
import 'package:***_mobile/screens/login_screen.dart';
import 'package:***_mobile/screens/venue_details_page.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(***());
}
class *** extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => UserRepository.instance(),
child: Consumer(
builder: (context, UserRepository user, _) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
'/browsing': (ctx) => BrowsingPage(),
'/venueDetails': (ctx) => VenueDetailPage(),
'/filmDetails': (ctx) => FilmDetailPage(),
'/login': (ctx) => LoginPage()
},
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
builder: (ctx, _) {
switch (user.status) {
case Status.Uninitialized:
return LoginPage();
case Status.Unauthenticated:
return LoginPage();
case Status.Authenticating:
return LoginPage();
case Status.Authenticated:
return BrowsingPage();
default:
return LoginPage();
}
},
);
},
),
);
}
}
Excuse for my language, i hope you will understand, what i was wrote.
You need wrap every widget, which you return from builder in Navigator
Navigator(
onGenerateRoute: (_) => MaterialPageRoute(
builder: (ctx) => Scaffold(
body: Stack(
children: [
Positioned.fill(
child: buildBody(
context.watch<AuthScopeViewModel>().screenType))
],
),
),
),
);

Authentication Flow with Flutter

I'm new to flutter. I am trying to set up an authentication flow. if the user is not logged in, I plan to build a MaterialApp with certain routes (eg Facebook Auth, Google Auth and Email Auth). If the user is logged in, they ll see another MaterialApp with routes such as HomePage, ListPage, CreatePage etc.
I tried but below codes fail. Anyone with experience can advise? thanks in advance
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import './pages/email.dart';
import './pages/auth.dart';
import './pages/home.dart';
import './pages/list.dart';
import './pages/create.dart';
import './scoped-models/main.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
final MainModel _model = MainModel();
bool _isAuthenticated = false;
#override
void initState() {
_model.autoAuthenticate();
_model.userSubject.listen((bool isAuthenticated) {
setState(() {
_isAuthenticated = isAuthenticated;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
print(_isAuthenticated);
return ScopedModel<MainModel>(
model: _model,
child: !_isAuthenticated == true
? MaterialApp(
theme: ThemeData(
primaryColor: Colors.lime, buttonColor: Colors.teal),
routes: {
'/': (BuildContext context) => AuthPage(),
'/email': (BuildContext context) => EmailPage(),
},
)
: MaterialApp(
theme: ThemeData(
primaryColor: Colors.lime, buttonColor: Colors.teal),
routes: {
'/': (BuildContext context) => HomePage(),
'/list': (BuildContext context) => ListPage(),
'/create': (BuildContext context) => CreatePage()
},
),
);
}