Состояния во флаттере позволяют нам динамически перестраивать страницы во флаттере. Я собираюсь показать быстрое применение использования состояний.

Чтобы использовать состояния, мы должны идентифицировать два объекта класса. Один расширяет statefulwidget, а другой расширяет State, который получает этот класс.

Т.е. здесь мы объявляем LoginPage и затем передаем его в _LoginPageState.

import 'package:flutter/material.dart';
import 'dart:developer';
import 'home.dart';
import 'package:firebase_auth/firebase_auth.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage>{
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context){
return Scaffold(
appBar:AppBar(
title:Text('Login'),
),
body: Container(
padding: EdgeInsets.all(20.0),
child: Form(
key: _formKey, // for validating the fields
child: Column(
//set password
children: <Widget>[
Text(
'Login Information',
style: TextStyle(fontSize: 20),
),
TextFormField(
onSaved: (value) => _email= value,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(labelText: "Email Address")),
TextFormField(
onSaved: (value) => _password=value.toString(),
obscureText: true,
decoration: InputDecoration(labelText: "Password")),
ElevatedButton(child: Text("Login"), onPressed: () async{
final form = _formKey.currentState;
print('form: $_formKey');
if(form != null && _email != null && _password != null){
form.save();
if (form.validate()){
try {
var result = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: _email.toString(), password: _password.toString());
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}  catch (e) {
print("error");
}
}
}
}),
],
),
),
),
);
}
}

Этот код приводит к следующей странице:

Если вы нажмете «Войти» с неправильными данными учетной записи, ничего не произойдет. Что, если мы хотим уведомить пользователя о том, что он ввел неправильные учетные данные?

import 'package:flutter/material.dart';
import 'dart:developer';
import 'home.dart';
import 'package:firebase_auth/firebase_auth.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage>{
final _formKey = GlobalKey<FormState>();
String? _password='';
String? _email='';
var _loggedin='';
void isloggedin(){
setState((){
_loggedin='No such user exists or password is incorrect';
});
print(_loggedin);
}
@override
Widget build(BuildContext context){
return Scaffold(
appBar:AppBar(
title:Text('Login'),
),
body: Container(
padding: EdgeInsets.all(20.0),
child: Form(
key: _formKey, // for validating the fields
child: Column(
//set password
children: <Widget>[
Text(
'Login Information',
style: TextStyle(fontSize: 20),
),
TextFormField(
onSaved: (value) => _email= value,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(labelText: "Email Address")),
TextFormField(
onSaved: (value) => _password=value.toString(),
obscureText: true,
decoration: InputDecoration(labelText: "Password")),
ElevatedButton(child: Text("Login"), onPressed: () async{
final form = _formKey.currentState;
print('form: $_formKey');
if(form != null && _email != null && _password != null){
form.save();
if (form.validate()){
try {
var result = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: _email.toString(), password: _password.toString());
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}  catch (e) {
print("error");
isloggedin();
}
}
}
}),
Text(_loggedin,style: TextStyle(fontSize: 20)),
],
),
),
),
);
}
}

Здесь мы добавляем переменную _loggedin, которая отслеживает неудачную попытку входа в систему. А затем используйте функцию setState() внутри функции isloggedin(), которую мы определили, чтобы указать Flutter пересоздать приложение. Внутри setstate мы устанавливаем переменную _loggedin в сообщение, которое мы выбираем «Такого пользователя не существует, или пароль неверный». Мы также добавляем новый текстовый виджет, который использует переменную _loggedin в качестве аргумента. Внутри нашего try catch мы добавляем функцию isloggedin(), и все готово!

Если вы хотите узнать, как создать это полноценное приложение, см. предыдущую статью, которую я создал: https://levelup.gitconnected.com/creating-a-basic-login-app-using-flutter-2493bba87263.