Search code examples
flutterproviderstate-management

SOLVED: Flutter Provider: Disappearing data on changing screen


I have used flutter 'provider' package a few times without a problem, but now I'm having a problem with it.

On login, I get the user role from the Firebase Database and change the 'role' property of my UserProvider class (which is extended by ChangeNotifier) via 'changeRole' function.

On navigation to the main screen, I try to fetch the value with the 'getRole' function from UserProvider, but it is an empty string. Somehow, changing Screens I lose the value.

I have tried printing the value on changing role and getting, and I can confirm that I change the value, but somehow it is lost after changing Screen.

Here is the relevant part of the code:

user_provider.dart

import 'package:flutter/cupertino.dart';

class UserProvider with ChangeNotifier {
  String _role = '';
  

  void changeRole(String newRole) {
    _role = newRole;
    print('CHANGEROLE: $_role'); // print statements added just for trying to solve this problem
    notifyListeners();
  }

  String get getRole {
    print('GETROLE: $_role');
    return _role;
  }
}

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    ChangeNotifierProvider(
      create: (context) => UserProvider(),
      child: MyApp(),
    ),
  );
}

...

login function on service

  void login() async {
    try {
      UserCredential userCredential = await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password);

      var data = await FirebaseFirestore.instance.collection('users').where('uid', isEqualTo: userCredential.user.uid).get();
      UserProvider().changeRole(data.docs[0]['role']);

      Navigator.of(context).pushNamed(MainScreen.routeName);

...

And here is where it should be displayed: main_screen.dart

...
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Consumer<UserProvider>(
              builder: (context, user, child) {
                return Text('This is your role: ${user.getRole}');
              },
            ),
...

Despite that, I get an empty string as it wasn't changed. The prints on the UserProvider model confirms that:

I/flutter (23760): CHANGEROLE: megauser
I/flutter (23760): GETROLE:

As you can see, I'm changing the role but the getter returns an empty string. What I'm doing wrong?

Edit: Thanks to Sifat Amin for pointing the solution. Just set the '_role' parameter as 'static' and that's all you need.


Solution

  • I guess changing the _role to static should suffice. As you are creating a new instance every time so the data gets lost. declaring the _role to static should suffice

    static String role ;
    

    so you don't need the get method at all. I think it should work