Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter state management with Provider

Tags:

flutter

I have a simple Provider class:

import 'package:flutter/foundation.dart';

class AppState with ChangeNotifier {
  bool _isLoggedIn = false;
  bool get isLoggedIn => _isLoggedIn;

  set isLoggedIn(bool newValue) {
    _isLoggedIn = newValue;
    notifyListeners();
  }
}

And in the login class I just set isLoggedIn to true if login is successful:

 void _signInWithEmailAndPassword(appState) async {
    try {
      final FirebaseUser user = await _auth.signInWithEmailAndPassword(
        ...
      );

      if (user != null) {
        appState.isLoggedIn = true;
        appState.userData = user.providerData;
        ...
      }
    } catch (e) {
      setState(() {
        _errorMessage = e.message;
      });
    }
  }

Pressing the back button on Android lets users go back to this page even after successfully logging in. So I wanted to know if Provider.of can be accessed before Widget build and redirect a user if isLoggedIn is true.

Now I have something like:

@override
  Widget build(BuildContext context) {
    final appState = Provider.of<AppState>(context);
...

This is only one use case for the login view, but I'm sure this functionality can be used in other cases.

like image 772
Ciprian Avatar asked May 20 '19 09:05

Ciprian


1 Answers

If you are going to use the FirebaseUser or Logged in user throughout your app, i would suggest that you add the Provider on the highest level of your app. Example

void main() {

   runApp(MyApp());
   }

class MyApp extends StatelessWidget {
  MyApp();

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider<FirebaseUser>.value(
          stream: FirebaseAuth.instance.onAuthStateChanged, // Provider here
        ),
      ],
      child: MaterialApp(
        title: 'My App',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.green,
          primarySwatch: Colors.green,
          accentColor: Colors.yellow,
        ),
        home: MainPage(),
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  MainPage({Key key, this.storage}) : super(key: key);
  final FirebaseStorage storage;
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<FirebaseUser>(context); // gets the firebase user
    bool loggedIn = user != null;

    return loggedIn ? HomePage() : LoginPage(); // Will check if the user is logged in. And will change anywhere in the app if the user logs in
  }
}

References

Fireship 185 Provider

Great Youtube video explaining the code

like image 134
Tinus Jackson Avatar answered Sep 25 '22 03:09

Tinus Jackson