Вход / регистрация провайдера флаттера - информация о классе пользователя пуста в приложении, почему? - PullRequest
0 голосов
/ 29 сентября 2019

Я создаю приложение во флаттере и использую «провайдер» для управления своим состоянием. Я пытаюсь заставить поток входа / регистрации работать с доступом и обновлением информации о пользователе через приложение. Однако, когда пользователь входит в систему или регистрируется, в теле ответа отображается вся информация, которая должна быть получена от 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')),

Извините за такой большой код, но я думаю, что все это необходимо для решения проблемы

Заранее спасибо!

...