Как удалить экран загрузки после входа / регистрации? (Трепетание / дротик)

#firebase #flutter #dart #google-cloud-firestore

#firebase #трепетание #дротик #google-облако-firestore

Вопрос:

Когда пользователь запускает мое приложение в первый раз, он может переключаться между формой регистрации и формой входа. После заполнения одной из этих форм он должен видеть экран загрузки до тех пор, пока пользователь не будет создан или не войдет в систему. В моем случае, к сожалению, экран загрузки не исчезает, хотя пользователь создан. Как я могу решить эту проблему?

форма входа:

 class SignIn extends StatefulWidget {
  final Function toggleView;
  SignIn({this.toggleView});

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

class _SignInState extends State<SignIn> {
  final AuthService _auth = AuthService();
  final _formKey = GlobalKey<FormState>();
  bool loading = false;

  // text field state
  String email = '';
  String password = '';
  String error = '';

  static const color = const Color(0xFF2F80ED);

  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            backgroundColor: Colors.white,
            resizeToAvoidBottomInset: false,
            body: Stack(
              children: <Widget>[
                Container(
                  child: Positioned(
                    top: 0,
                    right: 0,
                    child: Image.asset(
                      'assets/canvas-1-ws.png',
                    ),
                  ),
                ),
                Positioned(
                  top: 25.0,
                  left: 5.0,
                  child: IconButton(
                    icon: Icon(
                      Icons.close,
                      color: Colors.black,
                      size: 35.0,
                    ),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => Welcome(),
                        ),
                      );
                    },
                  ),
                ),
                Container(
                  child: Positioned(
                    bottom: 0,
                    left: 0,
                    child: Image.asset(
                      'assets/canvas-2-ws.png',
                    ),
                  ),
                ),
                Center(
                  child: Stack(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.only(
                          left: 50.0,
                          right: 50.0,
                        ),
                        child: Container(
                          child: Form(
                            key: _formKey,
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                Text(
                                  'Login',
                                  style: TextStyle(
                                    color: Colors.black,
                                    fontFamily: 'Roboto Black',
                                    fontSize: 35.0,
                                  ),
                                ),
                                SizedBox(
                                  height: 30.0,
                                ),
                                TextFormField(
                                  style: TextStyle(
                                    fontFamily: 'Roboto Light',
                                    color: Colors.black,
                                  ),
                                  cursorColor: Colors.black,
                                  decoration: InputDecoration(
                                    fillColor: Colors.black,
                                    hintText: 'Email',
                                    hintStyle: TextStyle(
                                      fontFamily: 'Roboto Light',
                                      color: Colors.black,
                                    ),
                                    enabledBorder: UnderlineInputBorder(
                                      borderSide: BorderSide(
                                        color: Colors.black,
                                        width: 1.0,
                                      ),
                                    ),
                                    focusedBorder: UnderlineInputBorder(
                                      borderSide: BorderSide(
                                        color: Colors.black,
                                        width: 1.0,
                                      ),
                                    ),
                                  ),
                                  validator: (val) => val.isEmpty
                                      ? 'Bitte gültige Email'
                                      : null,
                                  onChanged: (val) {
                                    setState(() => email = val);
                                  },
                                ),
                                SizedBox(
                                  height: 20.0,
                                ),
                                TextFormField(
                                    style: TextStyle(
                                      fontFamily: 'Roboto Light',
                                      color: Colors.black,
                                    ),
                                    cursorColor: Colors.black,
                                    decoration: InputDecoration(
                                      fillColor: Colors.black,
                                      hintText: 'Passwort',
                                      hintStyle: TextStyle(
                                        fontFamily: 'Roboto Light',
                                        color: Colors.black,
                                      ),
                                      enabledBorder: UnderlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.black,
                                          width: 1.0,
                                        ),
                                      ),
                                      focusedBorder: UnderlineInputBorder(
                                        borderSide: BorderSide(
                                          color: Colors.black,
                                          width: 1.0,
                                        ),
                                      ),
                                    ),
                                    obscureText: true,
                                    validator: (val) => val.isEmpty
                                        ? 'Bitte gültiges Passwort'
                                        : null,
                                    onChanged: (val) {
                                      setState(() => password = val);
                                    }),
                                SizedBox(
                                  height: 45.0,
                                ),
                                ButtonTheme(
                                  minWidth: 200,
                                  height: 50,
                                  child: RaisedButton(
                                    elevation: 0,
                                    color: color,
                                    textColor: Colors.white,
                                    shape: RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(30.0),
                                      side: BorderSide(color: color),
                                    ),
                                    child: Container(
                                      decoration: BoxDecoration(
                                        boxShadow: [
                                          BoxShadow(
                                            color: color,
                                            spreadRadius: 10.0,
                                            blurRadius: 20.0,
                                            offset: Offset(0, 3),
                                          ),
                                        ],
                                      ),
                                      child: Text(
                                        'Login',
                                        style: TextStyle(
                                            fontFamily: 'Roboto Light',
                                            fontSize: 25.0),
                                      ),
                                    ),
                                    onPressed: () async {
                                      if (_formKey.currentState.validate()) {
                                        setState(() => loading = true);
                                        dynamic result = await _auth
                                            .signInWithEmailAndPassword(
                                                email, password);
                                        if (result == null) {
                                          setState(() {
                                            error = 'Falsche Email/Password';
                                            loading = false;
                                          });
                                        }
                                      }
                                    },
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
  }
}
 

форма регистрации почти аналогична…

файл, в котором пользователь может переключаться между формами:

 class Welcome extends StatefulWidget {
  final Function toggleView;
  Welcome({this.toggleView});

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

class _WelcomeState extends State<Welcome> {
  static const color = const Color(0xFF2F80ED);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: <Widget>[
          Positioned(
            top: 0,
            right: 0,
            child: Image.asset('assets/canvas-1-ws.png'),
          ),
          Positioned(
            bottom: 0,
            left: 0,
            child: Image.asset('assets/canvas-2-ws.png'),
          ),
          Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Image.asset(
                  'assets/Skiclublogo_transparent.png',
                  scale: 4,
                ),
                SizedBox(
                  height: 40.0,
                ),
                ButtonTheme(
                  minWidth: 200,
                  height: 50,
                  child: RaisedButton(
                      elevation: 0,
                      color: color,
                      textColor: Colors.white,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                        side: BorderSide(color: color),
                      ),
                      child: Container(
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              color: color,
                              spreadRadius: 10.0,
                              blurRadius: 20.0,
                              offset: Offset(0, 3),
                            ),
                          ],
                        ),
                        child: Text(
                          'Registrieren',
                          style: TextStyle(
                              fontFamily: 'Roboto Light', fontSize: 25.0),
                        ),
                      ),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => Register(),
                          ),
                        );
                      }),
                ),
                SizedBox(
                  height: 40.0,
                ),
                ButtonTheme(
                  minWidth: 200,
                  height: 50,
                  child: RaisedButton(
                      elevation: 0,
                      color: color,
                      textColor: Colors.white,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0),
                        side: BorderSide(color: color),
                      ),
                      child: Container(
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              color: color,
                              spreadRadius: 10.0,
                              blurRadius: 20.0,
                              offset: Offset(0, 3),
                            ),
                          ],
                        ),
                        child: Text(
                          'Login',
                          style: TextStyle(
                              fontFamily: 'Roboto Light', fontSize: 25.0),
                        ),
                      ),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => SignIn(),
                          ),
                        );
                      }),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
 

файл авторизации, в котором пользователь создается или входит в систему:

 class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // create user obj based on FirrebaseUser
  User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  // auth change user stream
  Stream<User> get user {
    return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
  }

  // sign in anonmously
  Future signInAnon() async {
    try {
      AuthResult result = await _auth.signInAnonymously();
      FirebaseUser user = result.user;

      // create a new document for the user with the uid
      await DatabaseService(uid: user.uid).updateUserData(
          user.displayName, user.email, user.photoUrl, user.uid);
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // sign in email amp; password
  Future signInWithEmailAndPassword(String email, String password) async {
    try {
      AuthResult result = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      FirebaseUser user = result.user;
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // register with email amp; password
  Future registerWithEmailAndPassword(
      String email, String password, String name) async {
    try {
      AuthResult result = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
      FirebaseUser user = result.user;

      // update user info
      UserUpdateInfo userUpdateInfo = UserUpdateInfo();
      userUpdateInfo.displayName = name;
      await user.updateProfile(userUpdateInfo);
      await user.reload();
      user = await FirebaseAuth.instance.currentUser();

      // create a new document for the user with the uid
      await DatabaseService(uid: user.uid).updateUserData(
          user.displayName, user.email, user.photoUrl, user.uid);
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // sign out
  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  // current user
  void inputData() async {
    final FirebaseUser user = await _auth.currentUser();
    final uid = user.uid;
    // here you write the codes to input the data into firestore
  }
}
 

файл-оболочка, в котором приложение проверяет, является ли пользователь новым:

 class Wrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);
    print(user);

    // return either Home or Authenticate widget
    if (user == null) {
      return Welcome();
    } else {
      return DrawerNav();
    }
  }
}
 

файл экрана загрузки:

 class Loading extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Center(
        child: SpinKitWave(
          color: Colors.black,
          size: 50.0,
        ),
      ),
    );
  }
}
 

Большое вам спасибо, когда вы прочитали все это!

Ответ №1:

Вы не всегда вызываете setState после создания пользователя.

Это будет работать

                       onPressed: (){ if (_formKey.currentState.validate()) {
                                    setState(() => loading = true);
                                    dynamic result = await _auth
                                        .signInWithEmailAndPassword(
                                            email, password);
                                    setState(() => loading = false);
                                    if (result == null) {
                                      setState(() {
                                        error = 'Falsche Email/Password';
                                      });
                                    }
                                  }},
 

Комментарии:

1. Нет, это не работает. Когда я нажимаю кнопку входа, появляется экран загрузки, а после входа снова появляется экран…

2. Конечно, я удалил экран загрузки только после _auth.signInWithEmailAndPassword, как вы просили. Может быть, вы хотите перейти на другую страницу, поэтому используйте Navigator.push( контекст, MaterialPageRoute( builder: (context) => NewPage(), ), );

Ответ №2:

Я объясню тебе, мой друг

установите boolean переменную с именем loading

 loading = false;
 

если loading true отображать экран загрузки, то отображать пользовательский интерфейс формы с помощью ternary operator

при создании пользователя измените state loading значение, чтобы появился экран загрузки

  setState(() { loading=true; });
 

после создания пользователя state loading снова измените значение на false

  setState(() { loading=false; });
 

Это шаблон в build function

 loading==false?yourui():loading()