#firebase #flutter #firebase-authentication
#firebase #флаттер #firebase-аутентификация
Вопрос:
Я пишу приложение для своей компании и попытался добавить аутентификацию firebase для входа и регистрации в свое приложение. Приложение не показывает ошибок и успешно запускается.
Но когда пользователь пытается войти в систему с неправильным адресом электронной почты и паролем, вместо запрограммированного тоста отображается внутренняя ошибка flutter. А также я использовал общие настройки, чтобы пользователи оставались в системе.
Поэтому, когда пользователь пытается войти в систему с неправильными учетными данными, он показывает внутреннюю ошибку flutter, и когда приложение повторно открывается, вместо перехода на экран входа в систему оно использует неправильные учетные данные и переводит пользователя на главный экран, что смешно.
Это объявленные переменные:
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final _formKey = GlobalKey<FormState>();
TextEditingController _emailcontroller = TextEditingController();
TextEditingController _passwordcontroller = TextEditingController();
bool passvis = true;
bool loading = false;
И это функция для входа в систему:
Future loginForm() async {
FormState formSate = _formKey.currentState;
if (formSate.validate()) {
final User firebaseUser = (await firebaseAuth
.signInWithEmailAndPassword(
email: _emailcontroller.text,
password: _passwordcontroller.text)
.catchError((errMsg) {
displayToast("Error: " errMsg.toString(), context);
}))
.user;
if (firebaseUser != null) {
setState(() {
loading = true;
});
usersRef.child(firebaseUser.uid).once().then((DataSnapshot snap) {
if (snap.value != null) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return LocationHome();
}));
displayToast("Succesfully LoggedIn!", context);
} else {
firebaseAuth.signOut();
displayToast("No user found! Please try SignUp", context);
}
});
} else {
displayToast("Error Occured! Cannot log you in", context);
}
}
}
}
А для регистрации код приведен ниже:
Future validateForm() async {
FormState formSate = _formKey.currentState;
if (formSate.validate()) {
final User firebaseUser = (await firebaseAuth
.createUserWithEmailAndPassword(
email: _emailcontroller.text,
password: _passwordcontroller.text)
.catchError((errMsg) {
displayToast("Error: " errMsg.toString(), context);
}))
.user;
if (firebaseUser != null) {
Map userDataMap = {
"name": _namecontroller.text.trim(),
"email": _emailcontroller.text.trim(),
"phone": _phonecontroller.text.trim(),
};
usersRef.child(firebaseUser.uid).set(userDataMap);
displayToast("Succesfully Registered!", context);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return LocationHome();
}));
} else {
displayToast("User was unable to create", context);
}
}
}
}
Файл main.dart также закодирован правильно:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
SharedPreferences preferences = await SharedPreferences.getInstance();
var circle = preferences.getString("circle");
runApp(MaterialApp(
title: 'TaakStore',
home: circle == null ? Login() : Home(),
));
}
DatabaseReference usersRef =
FirebaseDatabase.instance.reference().child("users");
Не беспокойтесь о displayToast
функции. Это функция, созданная вручную с помощью flutter toast.
Комментарии:
1. Извините, произошла ошибка, но это не проблема, вместо круга в main.dart это электронная почта, и в функции входа есть общие настройки
Ответ №1:
Чтобы отобразить всплывающее окно, попробуйте выполнить следующее:
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailcontroller.text,
password: _passwordcontroller.text
);
} on FirebaseAuthException catch (e) {
displayToast("Error: " e.message.toString(), context);
print(e.message);
}
Чтобы проверить, вошел ли пользователь в систему или нет, используйте следующее:
FirebaseAuth.instance
.authStateChanges()
.listen((User user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
authStateChanges()
имеет тип Stream<User>
, который будет прослушивать любые изменения состояния пользователя. Поэтому, если пользователь вошел в систему, он вернет действительный объект user, и вы сможете перейти на главный экран. Поэтому нет необходимости использовать общие настройки.
Комментарии:
1. Спасибо, но куда добавить эти firebase.instace с помощью authstatechange
2. добавьте его в main.dart, создайте виджет streambuilder, который будет вызывать метод authStatechange и в соответствии с результатом перейдите на определенную страницу
3. Спасибо, не могли бы вы, пожалуйста, изменить мой код на свой код .. я в полном замешательстве
Ответ №2:
Для отображения тоста
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailcontroller.text,
password: _passwordcontroller.text
);
} on FirebaseAuthException catch (e) {
displayToast("Error: " e.message.toString(), context);
print(e.message);
}
Чтобы проверить, вошел ли пользователь в систему
//inside the main.dart in the "MaterialApp" widget
MaterialApp(home:buildHome(),)
buildHome(){return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.hasData) {
print(snapshot);
//if the user is logged in return what you want
return "";
} else {
//else return what you want also
return"";
}
},
);}
Комментарии:
1. Братан, все отлично, не беспокойся…. Но, пожалуйста, также укажите функцию для выхода из системы. А также как отобразить пользовательский тост вместо отображения ошибки, допущенной firebase
2. Нет. Я думаю, что проблема снова возникнет
3. Он не работает в соответствии с функцией входа в систему.. При нажатии кнопки входа в систему он переходит на главный экран, чего я не хочу