Непонятное поведение трепетания в окне пользователя / входа / выхода из системы - PullRequest
0 голосов
/ 02 апреля 2020

В последнее время я боролся с этим. Я не понимаю поведение трепетания здесь.

Я пытаюсь сделать страницу пользователя / логина / регистрации. Для этого я использую Firebase Cloud Firestore и FireBase Auth. У меня есть провайдер, который хранит статус пользователя

enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated, Register, AuthenticatingRegister, RegisterTransit, RegisterNS, AuthenticatingRegisterNS }

class UserRepository with ChangeNotifier {
  FirebaseAuth _auth;
  FirebaseUser _user;
  Status _status = Status.Uninitialized;

Так я реализую свою функцию входа в систему. SingUp, LogOut LogOut очень похожи.

  Future<bool> signIn(String email, String password) async {
    try {
      _status = Status.Authenticating;
      notifyListeners();
      await _auth.signInWithEmailAndPassword(email: email, password: password, );
      return true;
    } catch (e) {
      _status = Status.Unauthenticated;
      notifyListeners();
      return false;
    }
  } 

У меня есть пользовательский экран, когда в зависимости от состояния я выбираю, какой экран показывать.

class UserScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => UserRepository.instance(),
      child: Consumer(
        builder: (context, UserRepository user, _) {
          switch (user.status) {
            case Status.RegisterNS:
            case Status.AuthenticatingRegisterNS:
              return FormNS();
            case Status.RegisterTransit:
              return LoginMeio();
            case Status.Unauthenticated:
            case Status.Authenticating:
              return LoginPage();
            case Status.Authenticated:
              return UserInfoPage(user: user.user);
            case Status.Register:
            case Status.AuthenticatingRegister:
              return RegisterScreen();
            case Status.Uninitialized:
              return Splash();
            default:
              return Splash();
          }
        },
      ),
    );
  }
}

Я не обозначен снизу Вкладка Навигатор для навигации по приложению.

Все работает, как задумано, часть мелочи. Я инициализирую статус как неинициализированный на UserRepository провайдере. Каждый раз, когда я на короткое время открываю UserScreen, перед тем как я перенаправлюсь на нужный экран, отображается экран spla sh. Это прекрасно, когда пользователь впервые хочет перейти на UserScreen. Но после этого я просто хочу, чтобы правильная страница открывалась напрямую, не проходя через экран Spla sh.

Если мне не хватает четких просьб, скажите мне.

У меня вопрос. Если я go захожу на страницу и возвращаюсь на экран пользователя, как я могу предотвратить инициализацию статуса как Status.Uninitialized до того, как он распознает правильный статус и вернет правильную страницу?

1 Ответ

0 голосов
/ 02 апреля 2020

Чтобы войти в систему, вы вызываете это:

await _auth.signInWithEmailAndPassword(email: email, password: password, );

Как уже показывает использование await, эта операция является асинхронной: Firebase должна вызвать свои серверы аутентификации здесь, чтобы проверить электронную почту и комбинация пароля, и это занимает некоторое время.

Время, которое занимает этот вызов, зависит от многих факторов. Хотя это может быть довольно быстрым для вас, это может занять несколько секунд для некоторых ваших пользователей, которые находятся в более удаленных местах, или иным образом на более медленных соединениях типа inte rnet.

Но действительно, показывая spla sh очень короткий экран также не очень удобен для пользователя, поэтому у меня есть несколько вариантов, о которых я могу подумать:

  1. Во-первых, я подумаю, действительно ли вам нужно войти в систему. пользователь каждый раз. Аутентификация Firebase автоматически сохраняет состояние аутентификации пользователя и восстанавливает это состояние при перезапуске приложения. Поэтому вместо того, чтобы каждый раз вызывать signInWithEmailAndPassword, рассмотрите возможность использования await _auth.currentUser().

    К сожалению, это также асинхронная операция, поскольку Firebase необходимо проверить, действителен ли токен идентификатора пользователя (и обновить * 1035). * это иначе). Но это может занять меньше времени, чем вызов signInWithEmailAndPassword.

  2. Вы можете сохранить локальный флаг (например, в общих настройках ), который отмечает, что пользователь был подписан ранее, и используйте это, чтобы пропустить экран spla sh. Обратите внимание, что вход пользователя в систему, возможно, истек или произошел сбой, поэтому ваше предположение c (основанное на локальном флаге) может быть неверным, и в этом случае вы все равно можете захотеть показать экран spla sh.

  3. Вы можете отложить показ экрана spla sh на короткое время, чтобы предотвратить большую часть мигания. Скажем, вы заметили, что в среднем повторная аутентификация занимает менее 0,5 секунды. Вы можете изменить свой код так, чтобы экран spla sh отображался только через 0,5 секунды, чтобы пользователи не могли видеть, если это займет не более 0,5 секунды.

    Насколько это эффективно и какую точную точку отсечения следует использовать, зависит от распределения времени, необходимого для регистрации всех ваших пользователей. Таким образом, вы можете начать отслеживать по своим пользователям, сколько времени занимает вход в систему с помощью Firebase Analytics или мониторинга производительности.

...