Search code examples
flutterriverpodflutter-hooks

Getting error when trying to add WidgetRef parameter to the build method in Flutter


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(
    const ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends HookWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    Future<DocumentSnapshot<Map<String, dynamic>>> getUserData(userId) async {
      final userData = await FirebaseFirestore.instance
          .collection('users')
          .doc(userId)
          .get();

      return userData;
    }

    useEffect(() {
      if (FirebaseAuth.instance.currentUser != null) {
        final currentUserId = FirebaseAuth.instance.currentUser!.uid;

        getUserData(currentUserId).then((currentUserData) {
          var currentUser = CurrentUser(
            uid: currentUserId,
            mobile: currentUserData.data()!['mobile'],
            // some more fields
          );

          ref.read(currentUserProvider.notifier).updateCurrentUser(currentUser);
        });
      }

      return null;
    }, []);

    return MaterialApp(
      title: 'MyTitle',
      home: StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (ctx, snapshot) {
          if (snapshot.hasData) {
            return const TabsScreen();
          }
          return const SignInScreen();
        },
      ),
    );
  }
}

This is the code I have in my main.dart file. I am trying to set a state in Riverpod every time the app launches. I am using useEffect Flutter hook to achieve the same. But to set the state, I need to get ref. When I try to add a parameter WidgetRef ref to the build function, I get the following error -

'MyApp.build' ('Widget Function(BuildContext, WidgetRef)') isn't a valid override of 'StatelessWidget.build' ('Widget Function(BuildContext)').

I don't know if there is some syntax error, or if the MainApp widget should (somehow) be converted to statefulWidget, or I need to take a totally different approach to achieve what I need?

P.S.: I am importing all the required files. Just not pasted that code here.


Solution

  • Actually, as noted above, you need to use HookConsumerWidget instead of HookWidget so that you have access to ref in the build method:

    class MyApp extends HookConsumerWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context, WidgetRef ref) {...}
    

    You can also use HookConsumer to subtree the widget:

    HookConsumer(builder: (context, ref, child) {
          return Text(ref.watch(provider));
        },);