I am new to Flutter, and I am stuck as I am using shared_preferences for auto login feature for an app. Here's the code for it.
When the exception was thrown, this was the stack:
#0 localStorage (package:ui_task/loginform.dart)
#1 MyApp.build (package:ui_task/main.dart:135:8)
#2 StatelessElement.build (package:flutter/src/widgets/framework.dart:4706:28)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4632:15)
#4 Element.rebuild (package:flutter/src/widgets/framework.dart:4322:5)
bool? isLoginDoneBefore;
void main() {
runApp(MyApp());
}
// ignore: must_be_immutable
class MyApp extends StatelessWidget {
// This widget is the root of your application.
// late bool? isLoginDoneBefore = localStorage.getBool("isLoginSuccessful");
@override
void initState() {
getData();
}
getData() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
isLoginDoneBefore=prefs.getBool("isLoginSuccessful");
}
Widget build(BuildContext context) {
// ignore: unnecessary_null_comparison
if(localStorage==null || isLoginDoneBefore==null){
return MaterialApp(
title: 'Login Form',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
home: LoginFormWithAutoValidation(),
);
}
else {
return MaterialApp(
title: 'Login Form',
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
home: isLoginDoneBefore! ? afterLogin() : LoginFormWithAutoValidation(),
);
}
}
}
UPDATE : Adding the topmost stack file. And here's the loginform.dart:
late SharedPreferences localStorage;
class LoginFormWithAutoValidation extends StatefulWidget {
@override
_LoginFormWithAutoValidationState createState() => _LoginFormWithAutoValidationState();
// static Future init() async{
// localStorage = await SharedPreferences.getInstance();
// }
}
class _LoginFormWithAutoValidationState extends State<LoginFormWithAutoValidation> {
TextStyle style = TextStyle(fontFamily: 'Montserrat', fontSize: 20.0);
TextEditingController _passwordController = new TextEditingController();
TextEditingController _unameController = new TextEditingController();
final _formKey = new GlobalKey<FormState>();
late bool isLoginSuccessful;
late String? _uname;
late String? _password;
bool _autoValidate = false;
save() async{
// await LoginFormWithAutoValidation.init();
localStorage.setString('uname',_unameController.text.toString());
localStorage.setString('password',_passwordController.text.toString());
localStorage.setBool("isLoginSuccessful",true);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey[900],
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
. . . . .
Material(
// login button
onPressed: () {
if (_formKey.currentState!.validate()) {
save();
Navigator.push(context,MaterialPageRoute(builder: (context) {
return afterLogin();}));
} else {
setState(()
// validation error
_autoValidate = true;
});
}
You are defining localStorage
at the top of the loginform.dart
file, but you are not initializing it with await SharedPreferences.getInstance();
that is why the error is thrown. Apart from that i would not recommend storing the password in cleartext in shared_preferences
(if at all). It can easily be extracted. If you absolutely have to store it i would recommend: https://pub.dev/packages/flutter_secure_storage