Authentication class
class Authentication with ChangeNotifier{
String _authToken='';
String _userId= '';
String get authToken{
return _authToken;
}
String get userId{
return _userId;
}
bool get isTokenValid{
print(authToken);
return _authToken.isNotEmpty;
}
Future<void> signIn(Map<String,Object> payload) async {
final url = Uri.parse("http://10.0.2.2:9090/api/v1/auth/register");
try{
final response= await http.post(url,
headers: {'Content-Type': 'application/json'},
body: json.encode(
{
'firstName': payload['firstName'],
'email': payload['email'],
'password': payload['password'],
}
),);
final responseData = json.decode(response.body);
_authToken = responseData['token'];
_userId = responseData['userId'].toString();
}catch(exception){
rethrow;
}
notifyListeners();
}
Future<void> logIn(Map<String,Object> payload) async {
final url = Uri.parse("http://10.0.2.2:9090/api/v1/auth/authenticate");
try{
final response= await http.post(url,
headers: {'Content-Type': 'application/json'},
body: json.encode(
{
'email': payload['email'],
'password': payload['password'],
}
),);
final responseData = json.decode(response.body);
_authToken = responseData['token'];
_userId = responseData['userId'].toString();;
print("LogIn");
}catch(exception){
rethrow;
}
notifyListeners();
}
}
Main.dart
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Authentication()),
ChangeNotifierProxyProvider<Authentication,CreditData>(
create: (_) => CreditData('', [],''),
update: (ctx, authentication, prevCreditData) =>
CreditData(
authentication.authToken,prevCreditData == null ? [] : prevCreditData.data,
authentication.userId
),
),
],
child: Consumer<Authentication>(
builder: (ctx, auth, _) => MaterialApp(
title: "Money Management",
debugShowCheckedModeBanner: false,
home: auth.isTokenValid ? const Home():const AuthenticationScreen(),
routes: {
Home.routeName: (ctx) => const Home(),
Debit.routeName: (ctx) => const Debit()
},
),
)
);
}
}
When I use ChangeNotifierProxyProvider in-order to send the authToken and userId generated from Authentication class my springboot api is behaving infinte loop while the request was only once.
This is the way the server is repeating the request itself when I tried to debug threadpoolExecutor was in ifinite loop and I got no idea what to do (https://i.stack.imgur.com/vI4T3.png)
But when I use postman or ChangeNotifierProvider (not ChangeNotifierProxyProvider) i'm not getting this problem as you can see down
(https://i.stack.imgur.com/qRNj3.png)
Can someone please rectify the problem and mention why is it so happening?
Related
auth_service.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:zomato_clone/common/widgets/bottom_bar.dart';
import 'package:zomato_clone/constants/error_handling.dart';
import 'package:zomato_clone/constants/global_variables.dart';
import 'package:zomato_clone/constants/utils.dart';
import 'package:zomato_clone/features/admin/screens/admin_screen.dart';
import 'package:zomato_clone/models/user.dart';
import 'package:zomato_clone/providers/user_provider.dart';
class AuthService {
// sign up user
void signUpUser({
required BuildContext context,
required String email,
required String password,
required String name,
}) async {
try {
User user = User(
id: '',
name: name,
password: password,
email: email,
address: '',
type: '',
token: '',
cart: [],
);
http.Response res = await http.post(
Uri.parse('$uri/api/signup'),
body: user.toJson(),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
httpErrorHandling(
response: res,
context: context,
onSuccess: () {
showSnackBar(
context,
'Account created! Login with the same credentials!',
);
},
);
} catch (e) {
showSnackBar(context, e.toString());
}
}
// sign in user
void signInUser({
required BuildContext context,
required String email,
required String password,
}) async {
try {
http.Response res = await http.post(
Uri.parse('$uri/api/signin'),
body: jsonEncode({
'email': email,
'password': password,
}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
httpErrorHandling(
response: res,
context: context,
onSuccess: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Provider.of<UserProvider>(context, listen: false).setUser(res.body);
await prefs.setString(
'x-auth-token', jsonDecode(res.body)['token']);
Navigator.pushNamedAndRemoveUntil(
context,
Provider.of<UserProvider>(context, listen: false).user.type ==
'user'
? BottomBar.routeName
: AdminScreen.routeName,
(route) => false);
});
} catch (e) {
showSnackBar(context, e.toString());
}
}
// get user data
void getUserData(
BuildContext context,
) async {
try {
var userProvider = Provider.of<UserProvider>(context, listen: false);
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('x-auth-token');
if (token == null) {
prefs.setString('x-auth-token', '');
}
var tokenRes = await http.post(
Uri.parse('$uri/tokenIsValid'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': token!
},
);
var response = jsonDecode(tokenRes.body);
if (response == true) {
http.Response userRes = await http.get(
Uri.parse('$uri/'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'x-auth-token': token
},
);
userProvider.setUser(userRes.body);
}
} catch (e) {
showSnackBar(context, e.toString());
}
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:provider/provider.dart';
import 'package:zomato_clone/common/widgets/bottom_bar.dart';
import 'package:zomato_clone/features/admin/screens/admin_screen.dart';
import 'package:zomato_clone/features/auth/screens/auth_screen.dart';
import 'package:zomato_clone/features/auth/services/auth_service.dart';
import 'package:zomato_clone/providers/user_provider.dart';
import 'package:zomato_clone/router.dart';
import 'package:zomato_clone/splash_screen.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(MultiProvider(providers: [
ChangeNotifierProvider(
create: (context) => UserProvider(),
)
], child: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final AuthService authService = AuthService();
#override
void initState() {
super.initState();
authService.getUserData(context);
setState(() {});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.blue,
),
onGenerateRoute: (settings) => generateRoute(settings),
home: Provider.of<UserProvider>(context).user.email.isNotEmpty
? Provider.of<UserProvider>(context).user.type == 'user'
? const BottomBar()
: AdminScreen()
: const AuthScreen());
}
}
when i restart my app in flutter i first land on login page then go back to home page please tell me how to solve this problem.
when i tried a splashscreen it solve th problem when network is slow it goes back to loginpage then redirect to homePage help me solve this problem.
you should make getUserData to be Future and make a separate function to get the user date and make a local variable to handle loading state while fetching the data from the server and then use this variable later in home attribute
bool _loading = true ;
void prepareData()async{
await authService.getUserData(context);
_loading =false;
setState(() {});
}
#override
void initState() {
super.initState();
prepareData();
}
home: _loading?Center(child:CircularProgressIndicator()):Provider.of<UserProvider>(context).user.email.isNotEmpty
? Provider.of<UserProvider>(context).user.type == 'user'
? const BottomBar()
: AdminScreen()
: const AuthScreen());
The problem is that Hive is acting unexpectedly, and when the app closes or I restart it all, the data in the box is cleared.
main.dart:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(statusBarColor: Colors.transparent));
await Firebase.initializeApp();
await Hive.initFlutter();
Hive.registerAdapter(CredentialsModelAdapter());
Hive.registerAdapter(DoctorModelAdapter());
Hive.registerAdapter(DuserModelAdapter());
Hive.registerAdapter(DoctorAppointmentsAdapter());
Hive.registerAdapter(AppointmentStatusesAdapter());
Hive.registerAdapter(AccountTypeAdapter());
Hive.registerAdapter(UserAdapter());
await Hive.openBox<CredentialsModel>("cred");
await Hive.openBox<DuserModel>("doctor");
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _appRouter = app_router.AppRouter();
#override
Widget build(BuildContext context) {
return MaterialApp.router(
title: "x",
debugShowCheckedModeBanner: false,
routerDelegate: _appRouter.delegate(),
routeInformationParser: _appRouter.defaultRouteParser(),
);
}
}
Here is where I fetch the data from the api and store it in box:
#override
Future<Either<ApiFailures, dynamic>> signInWithEmailAndPassword(
{required String email, required String password}) async {
late Box<CredentialsModel> credentials;
var result;
try {
final response = await http.get(Uri.parse(
"xxxxxxxx"));
if (response.statusCode == 200) {
result = await json.decode(response.body);
if (result["AZSVR"] == "FAILED") {
return const Left(ApiFailures.authFailed());
} else {
var content = CredentialsModel.fromJson(result);
credentials = Hive.box("cred");
credentials.put('cred', content);
return right(result["api_token"]);
}
}
} on SocketException catch (e) {
return const Left(ApiFailures.noConnection());
} on HttpException {
return const Left(ApiFailures.notfound());
} catch (_) {
return const Left(ApiFailures.notfound());
}
return Right(result["api_token"]);
}
Where I call the box:
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:vwelfare/application/provider/doctor.repository.provider.dart';
import 'package:vwelfare/domain/models/doctor/duser.dart';
import '../../domain/models/credentials/credentials.dart';
class MyWidget extends HookConsumerWidget {
const MyWidget({super.key});
#override
Widget build(BuildContext context, WidgetRef ref) {
final Box<CredentialsModel> credBox = Hive.box("cred");
final Box<DuserModel> doctorBox = Hive.box("doctor");
final controller = useTextEditingController();
final uid = useState(0);
final cred = useState(const CredentialsModel());
return Scaffold(
body: ValueListenableBuilder(
valueListenable: credBox.listenable(),
builder: (context, Box<CredentialsModel> box, _) {
final cred = box.get("cred");
print(cred!.api_token);
final doctor = ref.watch(getDoctor(cred.api_token!));
return doctor.when(
data: (data) => data.fold(
(l) => ValueListenableBuilder(
valueListenable: doctorBox.listenable(),
builder: (context, Box<DuserModel> box, _) {
final model = box.get("doctor");
final doctor = model!.User;
if (doctor != null) {
return Center(
child: Text("${doctor.address}"),
);
} else {
return const Center(
child: Text("CONTACT US"),
);
}
}),
(r) => Center(child: Text("${r.User!.name}"))),
loading: () => const CircularProgressIndicator(),
error: (error, stackTrace) {
print(error);
return Center(
child: Text("$error hello"),
);
});
},
),
);
}
}
I don't know if I am doing something wrong but I followed the docs as they say:
1- registered the adapter
2- opened the box
3- called it in a widget
What am I doing wrong?
I am writing an app in flutter and need to send the users location as stream to my backend.After using the singleton as suggested in comment the logout works and it stops the stream,but after loging back streaming is not working.
I initialize my location stream by calling it in main:
Main:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
LocationService().locationStream;
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Semdatex Patient Portal',
debugShowCheckedModeBanner: false,
//theme for all screens
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: Colors.blue[100],
),
//all possible routes within the app
initialRoute: '/loginScreen',
routes: {
'/': (context) => const InitialSite(),
'/chat': (context) => const Chat(),
'/chatPage': (context) => const ChatPage(),
'/multipleChoice': (context) => const MultipleChoice(),
'/scale': (context) => const Scale(),
'/endScreen': (context) => const EndScreen(),
'/singleChoiceNew': (context) => const SelectionWindow(),
'/loginScreen': (context) => const LoginScreen(),
'/registerScreen': (context) => const RegisterScreen(),
},
);
}
}
LocationService:
import 'dart:async';
import 'package:location/location.dart';
import 'package:sdx_patient_portal/Datamodel/user_location.dart';
class LocationService {
static final LocationService _instance = LocationService._internal();
factory LocationService() => _instance;
LocationService._internal() {
getLocationOnchange();
}
var location = Location();
final StreamController<UserLocation> _locationController =
StreamController<UserLocation>.broadcast();
StreamSubscription<LocationData>? listen;
Stream<UserLocation> get locationStream => _locationController.stream;
void getLocationOnchange() async {
location.requestService().then((value) => {
location.requestPermission().then((permissionStatus) {
if (permissionStatus == PermissionStatus.granted) {
location.enableBackgroundMode(enable: true);
location.changeSettings(
interval: 10000, accuracy: LocationAccuracy.high);
listen = location.onLocationChanged.listen((locationData) {
_locationController.add(UserLocation(
locationData.latitude,
locationData.longitude,
locationData.altitude,
locationData.time));
});
}
})
});
}
StreamSubscription<LocationData>? getListener(){
return listen;
}
void dipose(){
listener?.cancel();
listener = null;
}
}
Here is the log in part in which I call the post after user has been loged in successfully:
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() => _State();
}
class _State extends State<LoginScreen> {
TextEditingController nameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final _formKey = GlobalKey<FormState>();
User user = User("", "");
String url = "http://10.0.2.2:9173/mob/login";
Future save() async {
var res = await http.post(Uri.parse(url),
headers: {'Content-Type': 'application/json'},
body: json.encode({'email': user.email, 'password': user.password}));
if (res.body.isEmpty) {
print('login wasn\'t successfull');
_showMyDialog();
} else {
var data = json.decode(res.body);
if (data["patientNumber"] == null) {
_showMyDialog();
} else {
await savePatientNumber(data["patientNumber"], data["lastAccess"]);
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('loggedIn', true);
//LocationService().getListener()?.resume();
LocationService().locationStream;
startLocationStream();
Navigator.pushNamed(context, '/');
}
}
}
I call the following POST after log in:
postLocation() async {
var patient = await getPatient();
var patNumber = patient[0]["PatNum"];
var l = (LocationService().locationStream);
const String url = "http://10.0.2.2:9173/mob/location";
UserLocation locationData;
l.listen((event) {
locationData = UserLocation(
event.latitude, event.longitude, event.altitude, event.time);
http.post(Uri.parse(url),
headers: {'Content-Type': 'application/json'},
body: json.encode({
'latitude': locationData.latitude,
'altitude': locationData.altitude,
'longitude': locationData.longitude,
'time': locationData.time,
'patientNumber': patNumber
}));
});
}
Then I call cancle the listener by signing out:
void signOut(context) async {
LocationService().dipose();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false);
}
Hoe can I get controll over the state of the app and rerun the services after re-login?
It is hard to follow as part of the code missing, but something like this could work.
Call startListeningLocation when a user logs in and stopListeningLocation when logs out.
class LocationService {
static final LocationService _instance = LocationService._internal();
factory LocationService() => _instance;
LocationService._internal();
final _location = Location();
final StreamController<UserLocation> _locationController =
StreamController<UserLocation>.broadcast();
StreamSubscription<LocationData>? _locationSubscription;
Stream<UserLocation> get locationStream => _locationController.stream;
void startListeningLocation() {
_location.requestService().then((value) => {
_location.requestPermission().then((permissionStatus) {
if (permissionStatus == PermissionStatus.granted) {
_location.enableBackgroundMode(enable: true);
_location.changeSettings(
interval: 10000, accuracy: LocationAccuracy.high);
_locationSubscription = _location.onLocationChanged.listen((locationData) {
_locationController.add(UserLocation(
locationData.latitude,
locationData.longitude,
locationData.altitude,
locationData.time));
});
}
})
});
}
void stopListeningLocation() {
_locationSubscription?.cancel();
}
}
I am trying to modify the following code that uses stateful widgets and provider package to use GetX package and stateless widgets instead. In a part of code it specifies if the user is authenticated or not to show the home or auth screen. This is the auth_controller.dart code:
class Auth with ChangeNotifier {
String? _token;
DateTime? _expiryDate;
String? _userId;
Timer? _authTimer;
bool get isAuth {
return token != null;
}
String? get token {
if (_expiryDate != null &&
_expiryDate!.isAfter(DateTime.now()) &&
_token != null) {
return _token;
}
return null;
}
String? get userId {
return _userId;
}
Future<void> _authenticate(
String email, String password, String urlSegment) async {
final host = Platform.isAndroid ? '10.0.2.2' : '127.0.0.1';
final url = Uri.parse('http://$host:8080/api/$urlSegment');
// final url = Uri.parse('http://10.0.2.2:8000/api/$urlSegment');
// final url = Uri.parse('http://127.0.0.1:8000/api/$urlSegment');
try {
final http.Response response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(
{
'email': email,
'password': password,
//'returnSecureToken': true,
},
),
);
final responseData = json.decode(response.body);
if (responseData['error'] != null) {
throw HttpException(responseData['error']['message']);
} else {
_token = responseData['idToken'];
_userId = responseData['id'];
_expiryDate = DateTime.now().add(
Duration(
seconds: responseData['expiresIn'],
),
);
}
_autoLogout();
notifyListeners();
final prefs = await SharedPreferences.getInstance();
final userData = json.encode(
{
'token': _token,
'userId': _userId,
'expiryDate': _expiryDate!.toIso8601String(),
},
);
prefs.setString('userData', userData);
} catch (error) {
throw error;
}
}
Future<void> signup(String email, String password) async {
return _authenticate(email, password, 'register');
}
Future<void> login(String email, String password) async {
return _authenticate(email, password, 'login');
}
Future<bool> tryAutoLogin() async {
final prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey('userData')) {
return false;
}
final Map<String, Object> extractedUserData = Map<String, Object>.from(
json.decode(prefs.getString('userData') as String));
final expiryDate =
DateTime.parse(extractedUserData['expiryDate'] as String);
if (expiryDate.isBefore(DateTime.now())) {
return false;
}
_token = extractedUserData['token'] as String;
_userId = extractedUserData['userId'] as String;
_expiryDate = expiryDate;
notifyListeners();
_autoLogout();
return true;
}
Future<void> logout() async {
_token = null;
_userId = null;
_expiryDate = null;
if (_authTimer != null) {
_authTimer!.cancel();
_authTimer = null;
}
notifyListeners();
final prefs = await SharedPreferences.getInstance();
// prefs.remove('userData');
prefs.clear();
}
void _autoLogout() {
if (_authTimer != null) {
_authTimer!.cancel();
}
final timeToExpiry = _expiryDate!.difference(DateTime.now()).inSeconds;
_authTimer = Timer(Duration(seconds: timeToExpiry), logout);
}
}
and this is main.dart:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Auth(),
),
],
child: Consumer<Auth>(
builder: (ctx, auth, _) => MaterialApp(
title: 'MyShop',
theme: ThemeData(
primarySwatch: Colors.purple,
accentColor: Colors.deepOrange,
fontFamily: 'Lato',
),
home: auth.isAuth
? MainScreen()
: FutureBuilder(
future: auth.tryAutoLogin(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: AuthScreen(),
),
routes: {
MainScreen.routeName: (ctx) => const MainScreen(),
UserAccountScreen.routeName: (ctx) => const UserAccountScreen(),
},
),
),
);
}
I tried to change the class to extend GetXController, also make some variables as observable by adding .obs at the end of them and listening to their changes by wrapping the listener part inside the Obx. But I don't know what should I do with isAuth variable? It seems my new code after modification can not update the isAuth state and it is always `false and this keeps the authentication page always up and no way to go into the application for users.
EDIT: This is the main.dart after modification:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: AuthController.instance.isAuth
? homeScreenRoute
: authenticationScreenRoute,
unknownRoute: GetPage(
name: '/not-found',
page: () => PageNotFound(),
transition: Transition.fadeIn),
getPages: [
GetPage(
name: rootRoute,
page: () {
return SiteLayout();
}),
GetPage(
name: authenticationScreenRoute,
page: () => const AuthenticationScreen()),
GetPage(name: homeScreenRoute, page: () => HomeScreen()),
],
debugShowCheckedModeBanner: false,
title: 'BasicCode',
theme: ThemeData(
scaffoldBackgroundColor: light,
textTheme: GoogleFonts.mulishTextTheme(Theme.of(context).textTheme)
.apply(bodyColor: Colors.black),
pageTransitionsTheme: const PageTransitionsTheme(builders: {
TargetPlatform.iOS: FadeUpwardsPageTransitionsBuilder(),
TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
}),
primarySwatch: Colors.blue,
),
// home: AuthenticationPage(),
);
}
}
You can wrap your stateless widget with GetBuilder(), like this:
GetBuilder<YourController>(
id: 'id_name',
builder: (controller) {
if (controller.isAuth) {
return OneWidget();
} else {
return SecondWidget();
}
}
Do you need use update(['id_name']) after change value of isAuth, this produce a rebuild of GetBuilder.
I was making an app using flutter and i have used shared_preferences package, and in auth stage i am facing an issue where when i build app user is logged in and when i log out and restart the app after killing it ,it still goes on homepage ,
Here is my code
main.dart
bool checkingKey;
Future<bool> checkKey() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool checkingKey=prefs.containsKey("jwt");
print("$checkingKey");
return checkingKey;
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Paint.enableDithering = true;
await checkKey().then((value){
checkingKey=value;
});
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// bool check=checkKey().then((bool value) => true);
print("hello=$checkingKey");
return MaterialApp(
home: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
),
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
color: Color(0xffccffcc),
child:checkingKey==false?LoginPage():mainPage()
),
),
),
routes: <String,WidgetBuilder>{
'/home':(BuildContext context)=>mainPage(),
'/login':(BuildContext context)=>LoginPage(),
}
);
}
}
login_signup_Auth.dart
Future<void> attemptLogIn(String username, String password,BuildContext context) async {
///?final storage =parent_inherit.of(context);
///?var verify=storage.verify;
SharedPreferences prefs = await SharedPreferences.getInstance();
print("$username $password");
final http.Response res = await http.post(
"https://green-earth.herokuapp.com/signin",
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
// 'authorization':'Bearer '+
},
body: jsonEncode(<String, String>{
"email": username,
"password": password
}),
);
if(res.statusCode == 200) {
prefs.setString('jwt',res.body);
var value=prefs.getString('jwt');
print("storage= ${value.isEmpty}");
Navigator.of(context).pushNamed('/home');
}
else{
return _showMyDialoglogin(context,res.statusCode);
}
}
void logoutOutOfApp(BuildContext context) async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
Navigator.of(context).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
}
On the second build without changing anything , the checking key variable is returned 'true' which i don't know ,how can it be possible!!!!!!
I am not getting what i am doing wrong ,also if u see any other problem which can make program efficient or any other code which shall be used .please tell
ThankYou very much!!
Why you are complicating things ?
Your main.dart can simply looks like this
bool checkingKey;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Paint.enableDithering = true;
var prefs = await SharedPreferences.getInstance();
checkingKey = prefs.containsKey("jwt");
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
print("hello=$checkingKey");
return MaterialApp(
home: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
),
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
color: Color(0xffccffcc),
child: !checkingKey ? LoginPage() : mainPage(),
),
),
),
routes: <String,WidgetBuilder>{
'/home':(BuildContext context) => mainPage(),
'/login':(BuildContext context) => LoginPage(),
},
);
}
}