Я создаю приложение во флаттере и использую «провайдер» для управления своим состоянием. Я пытаюсь заставить поток входа / регистрации работать с доступом и обновлением информации о пользователе через приложение. Однако, когда пользователь входит в систему или регистрируется, в теле ответа отображается вся информация, которая должна быть получена от API, и предполагается, что она должна быть присвоена моему классу User, однако, когда я пытаюсь получить доступ к имени пользователя на странице своей учетной записи, этовозвращается как пустая строка.
Я создал пользовательский класс с обязательными полями и моделью входа в систему и сервисом аутентификации, используя пакет провайдера. У меня также есть конечная точка API и файл, который имеет все это. Я также использую getIt для внедрения зависимостей.
мой класс пользователя ниже
class User {
String token;
String firstName;
String lastName;
String email;
String avatar;
User({
this.token,
this.firstName,
this.lastName,
this.email,
this.avatar,
});
User.initial()
: token = '',
firstName = '',
lastName = '',
email = '',
avatar = '';
User.fromJson(Map<String, dynamic> json){
token = json['token'];
firstName = json['firstName'];
lastName = json['lastName'];
email = json['email'];
avatar = json['avatar'];
}
Map<String, dynamic> toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
data['token'] = this.token;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['email'] = this.email;
data['avatar'] = this.avatar;
return data;
}
}
мой сервис аутентификации ниже
class AuthenticationService {
Api _api = locator<Api>();
StreamController<User> userController = StreamController<User>();
Stream<User> get userData => userController.stream;
Future<bool> login(String email, String password) async {
var success = await _api.login(email, password);
return success;
}
Future<bool> create_account(String firstName, String lastName, String email, String password) async {
var success = await _api.createAccount(firstName, lastName, email, password);
return success;
}
Future<bool> fetchUser(String token) async {
var fetchedUser = await _api.getUser(token);
print(fetchedUser);
var hasUser = fetchedUser != null;
if (hasUser) {
userController.add(fetchedUser);
}
return hasUser;
}
}
мой код менеджера API ниже
Future<bool> createAccount(String firstName, String lastName, String email, String password) async {
Map<String, String> headers = {"Content-type": "application/json"};
String body = '{"firstName": "$firstName", "lastName": "$lastName", "email": "$email", "password": "$password"}';
var response =
await http.post('${endpoint}/users', headers: headers, body: body);
var result = json.decode(response.body);
print(response.body);
if (response.statusCode == 201) {
return true;
} else {
return false;
}
}
Future<bool> login(String email, String password) async {
Map<String, String> headers = {"Content-type": "application/json"};
String body = '{"email": "$email", "password": "$password"}';
var response =
await http.post('$endpoint/auth/login', headers: headers, body: body);
var result = json.decode(response.body);
print(response.body);
if (response.statusCode == 200) {
appPreferences.setString("user_token", result['token']);
getUser(result['token']);
return true;
} else {
return false;
}
}
Future<User> getUser(String token) async {
Map<String, String> headers = {"Authorization": "$token"};
var response = await http.get('$endpoint/users/me', headers: headers);
print(response.body);
var result = json.decode(response.body);
return User(firstName: result['firstName'], lastName: result['lastName'], email: result['email'], avatar: result['avatar']);
}
}
мой код модели логина указан ниже
class LoginModel extends ChangeNotifier {
final AuthenticationService _authenticationService =
locator<AuthenticationService>();
ViewState _state = ViewState.Idle;
ViewState get state => _state;
void setState(ViewState viewState) {
_state = viewState;
notifyListeners();
}
Future<bool> login(String email, String password) async {
setState(ViewState.Busy);
var success = await _authenticationService.login(email, password);
setState(ViewState.Idle);
return success;
}
Future<bool> createAccount(
String firstName, String lastName, String email, String password) async {
setState(ViewState.Busy);
var success = await _authenticationService.create_account(
firstName, lastName, email, password);
setState(ViewState.Idle);
return success;
}
Future<bool> fetchUser(String token) async {
setState(ViewState.Busy);
var success = await _authenticationService.fetchUser(token);
setState(ViewState.Idle);
return success;
}
}
это мой on login pressed
код
AppButton(
text: AppStrings.loginButton,
isInverted: false,
onPressed: () async {
var loginSuccess = await model.login(
email_controller.text, password_controller.text);
if (loginSuccess) {
appPreferences.setBool("logged_in", true);
Navigator.popUntil(context, ModalRoute.withName('/'));
} else {
print("Login Failed");
_loginFailedAlert(context);
}
},
),
и мультипровайдер в моем файле main.dart
return MultiProvider(
providers: [
StreamProvider<UserLocation>.value(
value: LocationService().locationStream),
StreamProvider<User>(
initialData: User.initial(),
builder: (context) => AuthenticationService().userData,
),
ChangeNotifierProvider<ThemeChanger>(
builder: (_) => ThemeChanger(
isDark ? AppThemes.darkTheme() : AppThemes.lightTheme(),
),
),
],
child: MainApp());
и, наконец, страница моей учетной записи, где я пытаюсь получить доступ к информации
Widget build(BuildContext context) {
User user = Provider.of<User>(context);
return ChangeNotifierProvider<LoginModel>.value(
value: locator<LoginModel>(),
child: Consumer<LoginModel>(
builder: (context, model, child) => Scaffold(
...
SettingsButton(
user.firstName,
() =>
Navigator.pushNamed(context, '/settings/account')),
Извините за такой большой код, но я думаю, что все это необходимо для решения проблемы
Заранее спасибо!