Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provider listener does update wrapper widget #37

Closed
mansbjorn opened this issue Nov 11, 2021 · 1 comment
Closed

Provider listener does update wrapper widget #37

mansbjorn opened this issue Nov 11, 2021 · 1 comment

Comments

@mansbjorn
Copy link

mansbjorn commented Nov 11, 2021

I have been following the netninja tutorial on Firebase Auth but I have run into a problem. My signing is working well and the listener in my wrapper send the user directly to my homepage after signing in. However, my register page doesnt send the user onwards despite successfull registration. I have to update with hotrestart for the homescreen to appear.

Any and all help on this would be appreciated.

Here is my registration page:

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),
            key: _mainScaffoldKey,
            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,
                                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,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
  }
}

Here is my wrapper:

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();
    }
  }
}

Here is my main:

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(),
      ),
    );
  }
}

and finally here is my auth:

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;
    }
  }
}

let me know if more files/details are necessary in order to answer my question, I cannot understand why it is not loading the homepage properly.

@mansbjorn
Copy link
Author

I solved this by using the authenticate widget properly, like this:

import 'package:flutter/material.dart';
import 'package:the_book_club/UI/login_logout/login_widget.dart';
import 'package:the_book_club/UI/login_logout/signup_widget.dart';

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);
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant