Add User Profile

As a last step here with Auth, lets add a bit of visual feedback.

When a user logs in, let's show their image and display name on the screen, so they know they're logged in.

Because this display relies only on whether or not a user is logged in, we don't have to mess with our state or Redux. We simply build this widget.

1. Add needed container and files: lib/containers/user_profile/user_profile.dart

2. Build the widget to display a profile:

  1. // containers/user_profile/user_profile.dart
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_redux/flutter_redux.dart';
  5. import 'package:me_suite/models/app_state.dart';
  6. import 'package:me_suite/selectors/selectors.dart';
  7. import 'package:redux/redux.dart';
  8. class CurrentUserProfile extends StatelessWidget {
  9. @override
  10. Widget build(BuildContext context) {
  11. // This widget will change as the Redux store is updated,
  12. // So we need to connnect it to the store:
  13. return new StoreConnector<AppState, _ViewModel>(
  14. // Build a viewModel, as usual:
  15. converter: _ViewModel.fromStore,
  16. builder: (BuildContext context, _ViewModel vm) {
  17. // First, check to see if
  18. if (vm.displayName == null) {
  19. return new Container();
  20. } else {
  21. return new Center(
  22. child: new Column(
  23. children: <Widget>[
  24. new Text('Now signed in:',
  25. style: Theme.of(context).textTheme.display1),
  26. new Text(vm.displayName,
  27. style: Theme.of(context).textTheme.display2),
  28. ],
  29. ),
  30. );
  31. }
  32. });
  33. }
  34. }
  35. // A very basic viewModel.
  36. class _ViewModel {
  37. final String displayName;
  38. final String profileImgUrl;
  39. _ViewModel({@required this.displayName, @required this.profileImgUrl});
  40. static _ViewModel fromStore(Store<AppState> store) {
  41. return new _ViewModel(
  42. // We have to use the null aware operator here, so that
  43. // when there isn't a user, it just fails silently
  44. displayName: store.state.currentUser?.displayName,
  45. profileImgUrl: store.state.currentUser?.photoUrl,
  46. );
  47. };
  48. }

Finally, in your home_page, update your build method:

  1. // pages/home_page.dart
  2. Widget build(BuildContext context) {
  3. return new Scaffold(
  4. appBar: new AppBar(
  5. title: new Text(this.title),
  6. ),
  7. body: new Container(
  8. child: new Center(
  9. child: new Column(
  10. mainAxisAlignment: MainAxisAlignment.center,
  11. children: <Widget>[
  12. new GoogleAuthButtonContainer(),
  13. new Padding( // new
  14. padding: const EdgeInsets.symmetric(vertical: 16.0), // new
  15. child: new CurrentUserProfile(), // new
  16. ),
  17. new Text(
  18. 'You have pushed the button this many times:',
  19. ),
  20. new Counter(),
  21. ],
  22. ),
  23. ),
  24. ),
  25. floatingActionButton: new IncreaseCountButton(),
  26. );
  27. }

Once you've added this feature, you can click 'LogIn', and some text will appear showing the displayName of whichever use logged in.

NB: displayName is a property on FirebaseUser class, given to us by the flutter_fire package.

And now, we've built the boiler plate app. This is what you should have:

boiler app.com/ericwindmill/image/upload/v1518921043/flutter_by_example/boiler_plate_app.gif)