Держите пользователя в системе во флаттере (у приложения есть 2 разных логина и основного, один для клиента и один для водителя)

avatar
Nadjmeddine Ben Amor
1 июля 2021 в 16:07
290
1
0

Я делаю приложение во флаттере и работаю над аутентификацией. Я хочу знать, как я могу сохранить пользователя в системе после перезагрузки приложения. Теперь дело в том, что у моего приложения есть 2 типа пользователей (Клиент и Драйвер). Таким образом, у каждого есть свое пространство, например, вход и регистрация и основное (после входа в систему). Это код, который я использовал для регистрации.

class Initializer extends StatefulWidget {
// Access to this Screen
  static String id = 'initializer';

  @override
  _InitializerState createState() => _InitializerState();
}

class _InitializerState extends State<Initializer> {

  // Firebase Stuff
  final _auth = FirebaseAuth.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  User _user;
  // To Check if There's a Driver
  bool isDriver = true;
  void getCurrentUser() async {
    try {
      final getCurrentUser = _auth.currentUser;
      if (getCurrentUser != null) {
        getUserKind();
        _user = getCurrentUser;
      }
    } catch (e) {
      print(e);
    }
  }



getUserKind() async {
    try {
      // To fetch Database for Driver
      final QuerySnapshot checkOfDriver =
          await _firestore.collection('driver').where('uid', isEqualTo: _user.uid).get().catchError((error) {
        print(error);
      });

  if (checkOfDriver.docs.isEmpty)
    setState(() {
      isDriver = false;
    });
  else
    setState(() {
      isDriver = true;
    });
} catch (e) {
  print(e);
  return null;
}
  }
  @override
  void setState(fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  void initState() {
    super.initState();
    getCurrentUser();
  }

  @override
  Widget build(BuildContext context) {
    getCurrentUser();
    SizeConfig().init(context);
    return _user == null
        ? WelcomeScreen()
        : isDriver
            ? DriverMain()
            : ClientMain();
  }
}

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

Итак, что мне добавить в код или ...

Источник

Ответы (1)

avatar
Frank van Puffelen
1 июля 2021 в 16:13
0

Firebase уже сохраняет учетные данные пользователей и автоматически восстанавливает их при перезапуске приложения.

Но это асинхронный процесс, так как он требует обращения к серверу. К тому времени, когда ваш код getCurrentUser = _auth.currentUser запустится, этот асинхронный процесс еще не завершится, поэтому вы получите null.

.

Чтобы правильно реагировать на восстановление состояния аутентификации (и другие изменения), вам нужно использовать прослушиватель изменения состояния аутентификации, как показано в документации по состоянию аутентификации:

FirebaseAuth.instance
  .authStateChanges()
  .listen((User? user) {
    if (user == null) {
      print('User is currently signed out!');
    } else {
      print('User is signed in!');
    }
  });

Если вы хотите использовать это в своем пользовательском интерфейсе, вы обычно заключаете его в StreamBuilder вместо того, чтобы самостоятельно вызывать listen.

Nadjmeddine Ben Amor
1 июля 2021 в 16:36
0

Спасибо, но это не проблема. Пожалуйста, прочтите мое объяснение проблемы.

Frank van Puffelen
1 июля 2021 в 16:48
0

С чего ты взял, что проблема не в этом? Вы уже запускали код в отладчике? Если вы установите точку останова на getCurrentUser() внутри метода build, я предполагаю, что вы увидите, что он возвращает null. Я также ожидал бы, что isDriver будет иметь значение по умолчанию в этот момент, независимо от того, какое значение из базы данных. Причина этого в том, что вы не обрабатываете асинхронный характер восстановления учетной записи пользователя и чтения из Firestore, а StreamBuilder и FutureBuilder являются самым простым решением для этого.