Log In Flow Boiler Plate

This section is all about learning how to use the InheritedWidget for state management.

Eventually, we want this to happen:

  • App launches and shows loading spinner.
  • App checks local state and storage for an existing Firebase User.
  • If there is a user, login in the background and route to the home screen.
  • If not, route to the log in screen, and let user log in.This is actually the exact thing you'll learn in the Redux + Firebase Section. The difference is that here we're using the InheritedWidget as our central storage, ratherthan a Redux store. This is more 'vanilla Flutter'.

Auth Section Boiler Plate

To get the functionality described above, there's a couple things you'll need(before you implement hard logic).

First, some dumb old pages and routing. From the blank app, make these changes:

1. Create a new file in the lib alongside main called app.dart.

  1. lib/
  2. |-app.dart
  3. |-main.dart

In that file, copy and paste this. There's nothing fancy here. For now, this'll just be where you keep some appinformation, like theme data and routes.

  1. import 'package:advanced_app/screens/auth_screen.dart';
  2. import 'package:advanced_app/screens/home_screen.dart';
  3. import 'package:flutter/material.dart';
  4. class AppRootWidget extends StatefulWidget {
  5. @override
  6. AppRootWidgetState createState() => new AppRootWidgetState();
  7. }
  8. class AppRootWidgetState extends State<AppRootWidget> {
  9. ThemeData get _themeData => new ThemeData(
  10. primaryColor: Colors.cyan,
  11. accentColor: Colors.indigo,
  12. scaffoldBackgroundColor: Colors.grey[300],
  13. );
  14. @override
  15. Widget build(BuildContext context) {
  16. return new MaterialApp(
  17. title: 'Inherited',
  18. theme: _themeData,
  19. routes: {
  20. '/': (BuildContext context) => new HomeScreen(),
  21. '/auth': (BuildContext context) => new AuthScreen(),
  22. },
  23. );
  24. }
  25. }

2. Update Main File

In main.dart, erase everything and add this:

  1. // main.dart
  2. import 'package:advanced_app/app.dart';
  3. import 'package:advanced_app/app_state_container.dart';
  4. import 'package:flutter/material.dart';
  5. void main() {
  6. runApp(new AppRootWidget());
  7. }

3. Add HomeScreen

Add a new directory called screens in lib, and a file called home-screen.dart

  1. lib/
  2. |-screens/
  3. |-home_screen.dart
  4. |-app.dart
  5. |-main.dart

Just another basic widget in that file (for now):

  1. class HomeScreen extends StatefulWidget {
  2. @override
  3. HomeScreenState createState() => new HomeScreenState();
  4. }
  5. class HomeScreenState extends State<HomeScreen> {
  6. @override
  7. Widget build(BuildContext context) {
  8. return new Scaffold(
  9. appBar: new AppBar(
  10. title: new Text('Suite'),
  11. ),
  12. body: new Center(
  13. child: new Text(appState.user.displayName),
  14. ),
  15. );
  16. }
  17. }

4. Add AuthScreen

Add a file called auth_screen.dart along side the home_screen.

  1. lib/
  2. |-screens/
  3. |-home_screen.dart
  4. |-auth_screen.dart
  5. |-app.dart
  6. |-main.dart

Just another basic widget in that file (for now).

Notice that the onPressed callback for the RaisedButton simple prints right now. No logic to be had.

  1. // screens/auth_screen.dart
  2. import 'package:flutter/material.dart';
  3. class AuthScreen extends StatefulWidget {
  4. @override
  5. AuthScreenState createState() {
  6. return new AuthScreenState();
  7. }
  8. }
  9. class AuthScreenState extends State<AuthScreen> {
  10. @override
  11. Widget build(BuildContext context) {
  12. var width = MediaQuery.of(context).size.width;
  13. return new Container(
  14. width: width,
  15. child: new Column(
  16. mainAxisAlignment: MainAxisAlignment.center,
  17. crossAxisAlignment: CrossAxisAlignment.center,
  18. children: <Widget>[
  19. new RaisedButton(
  20. onPressed: () => print('Log in!'),
  21. color: Colors.white,
  22. child: new Container(
  23. width: 230.0,
  24. height: 50.0,
  25. alignment: Alignment.center,
  26. child: new Row(
  27. mainAxisAlignment: MainAxisAlignment.center,
  28. children: [
  29. new Padding(
  30. padding: const EdgeInsets.only(right: 20.0),
  31. child: new Image.network(
  32. 'http://diylogodesigns.com/blog/wp-content/uploads/2016/04/google-logo-icon-PNG-Transparent-Background.png',
  33. width: 30.0,
  34. ),
  35. ),
  36. new Text(
  37. 'Sign in With Google',
  38. textAlign: TextAlign.center,
  39. style: new TextStyle(
  40. fontSize: 16.0,
  41. ),
  42. ),
  43. ],
  44. ),
  45. ),
  46. ),
  47. ],
  48. ),
  49. );
  50. }
  51. }

If you launch right now, it works, but it does nothing.

That's it for the app boiler plate!