Login New User

Right now, when you start the app, it's showing a spinner for 2 seconds, thenrouting to the log in page.

What it should be doing is checking to see if a user exists on this devicein this app. If so, log that use in, otherwise, defer to the auth page.First, handle the case that a user does in-fact exist. That'll start in theAppStateContainer.

1. Replace 'startCountdown' with 'initUser'

In this app I've only set up Google OAuth via Firebase, so you'll see classesand methods that refer to GoogleUser.

  1. // lib/app_state_container.dart
  2. class _AppStateContainerState extends State<AppStateContainer> {
  3. AppState state;
  4. // This is used to sign into Google, not Firebase.
  5. GoogleSignInAccount googleUser; // new
  6. // This class handles signing into Google.
  7. // It comes from the Firebase plugin.
  8. final googleSignIn = new GoogleSignIn(); // new
  9. @override
  10. void initState() {
  11. super.initState();
  12. if (widget.state != null) {
  13. state = widget.state;
  14. } else {
  15. state = new AppState.loading();
  16. // Call a separate function because you can't use
  17. // async functionality in initState()
  18. initUser(); // new
  19. }
  20. }
  21. // All new:
  22. // This method is called on start up no matter what.
  23. Future<Null> initUser() async {
  24. // First, check if a user exists.
  25. googleUser = await _ensureLoggedInOnStartUp();
  26. // If the user is null, we aren't loading anyhting
  27. // because there isn't anything to load.
  28. // This will force the homepage to navigate to the auth page.
  29. if (googleUser == null) {
  30. setState(() {
  31. state.isLoading = false;
  32. });
  33. } else {
  34. // Do some other stuff, handle later.
  35. }
  36. }
  37. Future<GoogleSignInAccount> _ensureLoggedInOnStartUp() async {
  38. // That class has a currentUser if there's already a user signed in on
  39. // this device.
  40. GoogleSignInAccount user = googleSignIn.currentUser;
  41. if (user == null) {
  42. // but if not, Google should try to sign one in whos previously signed in
  43. // on this phone.
  44. user = await googleSignIn.signInSilently();
  45. }
  46. // NB: This could still possibly be null.
  47. googleUser = user;
  48. return user;
  49. }

This code alone will lead you back to this

Sign in with google

2. Make The Log In Button Do Something

Start this section in the auth_screen.dart file.

If you're seeing this Login page, that means you have no Google accountassociated with this device and app. So when you click the button, you needto both log into Google and then log into Firebase (which will happen in thebackground).

The auth screen will only have a few minor tweaks in the build method:

  1. // screens/auth_screen.dart
  2. // ...
  3. Widget build(BuildContext context) {
  4. var width = MediaQuery.of(context).size.width;
  5. // Get access to the AppState
  6. final container = AppStateContainer.of(context); // new
  7. return new Container(
  8. width: width,
  9. child: new Column(
  10. mainAxisAlignment: MainAxisAlignment.center,
  11. crossAxisAlignment: CrossAxisAlignment.center,
  12. children: <Widget>[
  13. new RaisedButton(
  14. // Call a method from the state (!!!)
  15. onPressed: () => container.logIntoFirebase(), // updated
  16. // ...

Add that method into your _AppStateContainerState class:

  1. // app_state_container.dart
  2. Future<Null> logIntoFirebase() async {
  3. // This method will be used in two cases,
  4. // To make it work from both, we'll need to see if theres a user.
  5. // When fired from the button on the auth screen, there should
  6. // never be a googleUser
  7. if (googleUser == null) {
  8. // This built in method brings starts the process
  9. // Of a user entering their Google email and password.
  10. googleUser = await googleSignIn.signIn();
  11. }
  12. // This is how you'll always sign into Firebase.
  13. // It's all built in props and methods, so not much work on your end.
  14. FirebaseUser firebaseUser;
  15. FirebaseAuth _auth = FirebaseAuth.instance;
  16. try {
  17. // Authenticate the GoogleUser
  18. // This will give back an access token and id token
  19. GoogleSignInAuthentication googleAuth = await googleUser.authentication;
  20. // Sign in to firebase with that:
  21. firebaseUser = await _auth.signInWithGoogle(
  22. accessToken: googleAuth.accessToken,
  23. idToken: googleAuth.idToken,
  24. );
  25. // Not necessary
  26. print('Logged in: ${firebaseUser.displayName}');
  27. setState(() {
  28. // Updating the isLoading will force the Homepage to change because of
  29. // The inheritedWidget setup.
  30. state.isLoading = false;
  31. // Add the use to the global state
  32. state.user = firebaseUser;
  33. });
  34. } catch (error) {
  35. print(error);
  36. return null;
  37. }
  38. }

That code is enough to log in. Hit that button.