首页 > 解决方案 > 提供者侦听器确实更新了包装器小部件

问题描述

我一直在关注Firebase Auth上的 netninja 教程,但遇到了问题。我的签名运行良好,我的包装器中的侦听器在登录后直接将用户发送到我的主页。但是,尽管注册成功,我的注册页面并没有继续发送用户。对此的任何和所有帮助将不胜感激。

这是我的注册页面:

class SignUpWidget extends StatefulWidget {
  @override
  SignUpState createState() => SignUpState();
}

class SignUpState extends State<SignUpWidget> {
  final AuthService _auth = AuthService();
  final _formKey = GlobalKey<FormState>();
  String error = '';
  bool loading = false;

  // text field state
  String displayName = '';
  String email = '';
  String password = '';
   
  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            backgroundColor: const Color.fromARGB(255, 69, 90, 100),
            body: SafeArea(
              child: Container(
                alignment: Alignment.center,
                padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
                child: Column(
                  children: <Widget>[
                    Card(
                      elevation: 2.0,
                      color: Colors.white,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(8.0),
                      ),
                      child: Form(
                        key: _formKey,
                        child: Column(
                          children: <Widget>[
                            Container(
                              padding:
                                  const EdgeInsets.only(top: 30, bottom: 30),
                              child: const Icon(
                                FontAwesomeIcons.bookOpen,
                                size: 60,
                                color: Color.fromARGB(255, 69, 90, 100),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.only(
                                top: 1.0,
                                bottom: 1.0,
                                left: 25.0,
                                right: 25.0,
                              ),
                              child: TextFormField(
                                validator: (val) =>
                                    val!.isEmpty ? 'Enter your name' : null,
                                onChanged: (val) {
                                  setState(() => displayName = val);
                                },
                                style: const TextStyle(
                                  fontFamily: "Montserrat",
                                  fontSize: 16.0,
                                  color: Colors.black,
                                ),
                                decoration: const InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    FontAwesomeIcons.solidUser,
                                    color: Color.fromARGB(255, 69, 90, 100),
                                    size: 22.0,
                                  ),
                                  hintText: "Enter name",
                                  hintStyle: TextStyle(
                                    fontFamily: "Montserrat",
                                    fontSize: 18.0,
                                  ),
                                ),
                              ),
                            ),
                            Container(
                              width: 250.0,
                              height: 1.0,
                              color: Colors.grey,
                            ),
                            Padding(
                              padding: const EdgeInsets.only(
                                top: 5.0,
                                bottom: 5.0,
                                left: 25.0,
                                right: 25.0,
                              ),
                              child: TextFormField(
                                validator: (val) =>
                                    val!.isEmpty ? 'Enter your email' : null,
                                onChanged: (val) {
                                  setState(() => email = val);
                                },
                                style: const TextStyle(
                                  fontFamily: "Montserrat",
                                  fontSize: 16.0,
                                  color: Colors.black,
                                ),
                                decoration: const InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    FontAwesomeIcons.solidEnvelope,
                                    color: Color.fromARGB(255, 69, 90, 100),
                                    size: 22.0,
                                  ),
                                  hintText: "Enter email",
                                  hintStyle: TextStyle(
                                    fontFamily: "Montserrat",
                                    fontSize: 18.0,
                                  ),
                                ),
                              ),
                            ),
                            Container(
                              width: 250.0,
                              height: 1.0,
                              color: Colors.grey,
                            ),
                            Padding(
                              padding: const EdgeInsets.only(
                                top: 5.0,
                                bottom: 5.0,
                                left: 25.0,
                                right: 25.0,
                              ),
                              child: TextFormField(
                                validator: (val) => val!.length < 6
                                    ? 'Enter a password 6+ chars long'
                                    : null,
                                obscureText: true,
                                focusNode: focusPassword,
                                controller: passwordController,
                                onChanged: (val) {
                                  setState(() => password = val);
                                },
                                style: const TextStyle(
                                  fontFamily: "Montserrat",
                                  fontSize: 16.0,
                                  color: Colors.black,
                                ),
                                decoration: const InputDecoration(
                                  border: InputBorder.none,
                                  icon: Icon(
                                    FontAwesomeIcons.lock,
                                    color: Color.fromARGB(255, 69, 90, 100),
                                    size: 22.0,
                                  ),
                                  hintText: "Enter password",
                                  hintStyle: TextStyle(
                                    fontFamily: "Montserrat",
                                    fontSize: 18.0,
                                  ),
                                ),
                              ),
                            ),
                            Container(
                              width: 250.0,
                              height: 1.0,
                              color: Colors.grey,
                            ),
                            Container(
                              margin: const EdgeInsets.only(top: 40.0),
                              decoration: const BoxDecoration(
                                borderRadius:
                                    BorderRadius.all(Radius.circular(5.0)),
                                boxShadow: <BoxShadow>[
                                  BoxShadow(
                                    color: AppColours.colorStart,
                                    offset: Offset(1.0, 6.0),
                                    blurRadius: 20.0,
                                  ),
                                  BoxShadow(
                                    color: AppColours.colorEnd,
                                    offset: Offset(1.0, 6.0),
                                    blurRadius: 20.0,
                                  ),
                                ],
                                gradient: LinearGradient(
                                  colors: [
                                    AppColours.colorEnd,
                                    AppColours.colorStart
                                  ],
                                  begin: FractionalOffset(0.2, 0.2),
                                  end: FractionalOffset(1.0, 1.0),
                                  stops: [0.1, 1.0],
                                  tileMode: TileMode.clamp,
                                ),
                              ),
                              child: MaterialButton(
                                highlightColor: Colors.transparent,
                                splashColor: AppColours.colorEnd,
                                child: const Padding(
                                  padding: EdgeInsets.symmetric(
                                    vertical: 10.0,
                                    horizontal: 42.0,
                                  ),
                                  child: Text(
                                    "Register",
                                    style: TextStyle(
                                      fontFamily: "Montserrat-bold",
                                      color: Colors.white,
                                      fontSize: 22.0,
                                    ),
                                  ),
                                ),
                                onPressed: () async {
                                  if (_formKey.currentState!.validate()) {
                                    setState(() => loading = true);
                                    dynamic result = await _auth
                                        .registerWithEmailandPassword(
                                            displayName, email, password);
                                    if (result == null) {
                                      setState(() {
                                        error = 'please supply a valid email';
                                        loading = false;
                                      });
                                    }
                                  }
                                },
                              ),
                            ),
                            SizedBox(
                              height: 20,
                            ),
                            Text(
                              error,
                              style: TextStyle(
                                color: Colors.red,
                                fontSize: 14,
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.only(top: 20),
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Container(
                                    decoration: const BoxDecoration(
                                      gradient: LinearGradient(
                                        colors: [
                                          Colors.black12,
                                          Colors.black,
                                        ],
                                        // ignore: use_named_constants
                                        begin: FractionalOffset(0.0, 0.0),
                                        // ignore: use_named_constants
                                        end: FractionalOffset(1.0, 1.0),
                                        stops: [0.0, 1.0],
                                        tileMode: TileMode.clamp,
                                      ),
                                    ),
                                    width: 100.0,
                                    height: 1.0,
                                  ),
                                  const Padding(
                                    padding: EdgeInsets.only(
                                        left: 15.0, right: 15.0),
                                    child: Text(
                                      "Or register with",
                                      style: TextStyle(
                                        color: Colors.black,
                                        decoration: TextDecoration.none,
                                        fontSize: 16.0,
                                        fontFamily: "Montserrat",
                                      ),
                                    ),
                                  ),
                                  Container(
                                    decoration: const BoxDecoration(
                                      gradient: LinearGradient(
                                        colors: [
                                          Colors.black,
                                          Colors.black12,
                                        ],
                                        begin: FractionalOffset(0.0, 0.0),
                                        end: FractionalOffset(1.0, 1.0),
                                        stops: [0.0, 1.0],
                                        tileMode: TileMode.clamp,
                                      ),
                                    ),
                                    width: 100.0,
                                    height: 1.0,
                                  ),
                                ],
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.only(
                                top: 20,
                                bottom: 20,
                              ),
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: <Widget>[
                                  GestureDetector(
                                    onTap: () => {},
                                    child: Container(
                                      child: const Icon(
                                        FontAwesomeIcons.facebook,
                                        color: Color(0xFF0084ff),
                                        size: 60,
                                      ),
                                    ),
                                  ),
                                  GestureDetector(
                                    onTap: () => {},
                                    child: Container(
                                      child: const Icon(
                                        FontAwesomeIcons.instagram,
                                        color: Color.fromARGB(255, 240, 58, 83),
                                        size: 60,
                                      ),
                                    ),
                                  ),
                                  GestureDetector(
                                    onTap: () => {},
                                    child: Container(
                                      child: const Icon(
                                        FontAwesomeIcons.twitter,
                                        color: Color(0xFF0084ff),
                                        size: 60,
                                      ),
                                    ),
                                  ),
                                  GestureDetector(
                                    onTap: () => {},
                                    child: Container(
                                      padding: const EdgeInsets.only(top: 5),
                                      child: const Image(
                                        height: 50,
                                        width: 50,
                                        image: AssetImage(
                                            'images/google_logo.png'),
                                      ),
                                      //FontAwesomeIcons.google,
                                      //color: const Color(0xFF0084ff),
                                      //size: 60,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
  }
}

这是我的包装:

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

    //return either homepage or Login widget
    if (user == null) {
      return LoginWidget();
    } else {
      return HomePage();
    }
  }
}

这是我的主要内容:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(App());
}

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  final Future<FirebaseApp> _initialization = Firebase.initializeApp();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initialization,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return const SomethingWentWrong();
        }
        if (snapshot.connectionState == ConnectionState.done) {
          return const MyApp();
        }
        return const CircularProgressIndicator();
      },
    );
  }
}

class SomethingWentWrong extends StatelessWidget {
  const SomethingWentWrong({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Row(
        children: const <Widget>[
          Text('something went wrong!'),
        ],
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamProvider<User?>.value(
      value: AuthService().user,
      initialData: null,
      child: MaterialApp(
        title: 'The Book Club',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          canvasColor: const Color.fromARGB(255, 207, 216, 220),
          fontFamily: 'Montserrat-SemiBold',
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: Wrapper(),
      ),
    );
  }
}

最后这是我的身份验证:

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  //auth change user stream
  Stream<User?> get user {
    return _auth.authStateChanges();
  }

  //sign in with email and password
  Future logInWithEmailandPassword(String email, String password) async {
    try {
      UserCredential result = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
      User? user = result.user;
      return user;
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  //register with email and password
  Future registerWithEmailandPassword(
      String name, String email, String password) async {
    try {
      UserCredential result = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
      User? user = result.user;
      return 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;
    }
  }
}

让我知道是否需要更多文件/详细信息才能回答我的问题,我不明白为什么它没有正确加载主页。

标签: flutterfirebase-authenticationstreamlistenerflutter-provider

解决方案


我通过正确使用我的身份验证小部件解决了这个问题,如下所示:

class Authenticate extends StatefulWidget {
  @override
  _AuthenticateState createState() => _AuthenticateState();
}

class _AuthenticateState extends State<Authenticate> {
  bool showLogIn = true;
  void toggleView() {
    setState(() => showLogIn = !showLogIn);
  }

  @override
  Widget build(BuildContext context) {
    if (showLogIn) {
      return LoginWidget(toggleView: toggleView);
    } else {
      return SignUpWidget(toggleView: toggleView);
    }
  }
}

推荐阅读