Flutter + Hive Check if value is present in box in Future Builder

1,105

Solution 1

The problem is with the first line of code in your build function. You're trying to get the user box from Hive without opening it first. Here is what can you do instead:

@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Startup Name Generator',
    theme: ThemeData(
      appBarTheme: const AppBarTheme(
        backgroundColor: Color(0xFF2036B8),
        foregroundColor: Colors.white,
      ),
    ),
    home: FutureBuilder<Box>(
      future: Hive.openBox('user'),
      builder: (BuildContext context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          } else {
            if (snapshot.data?.get('token') != null) {
              return const ProjectView();
            } else {
              return const LoginView();
            }
          }
        } else {
          return Scaffold();
        }
      },
    ),
  );
}

Solution 2

Part 1 of the issue is that you were trying to access user before opening. Secondly, I believe you need to check if the snapshot.hasData before proceeding with any operation i.e.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      theme: ThemeData(
        appBarTheme: const AppBarTheme(
          backgroundColor: Color(0xFF2036B8),
          foregroundColor: Colors.white,
        ),
      ),
      home: FutureBuilder(
        future: Hive.openBox<YourUserModelBox>('user'),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Text(snapshot.error.toString());
            } else if (snapshot.hasData) {
              if (snapshot.data is YourUserModelBox) {
                final user = snapshot.data as YourUserModelBox;
                if (user.get('token') != null) {
                  return const ProjectView();
                } else {
                  return const LoginView();
                }
              } else {
                Scaffold();
              }
            }
          } else {
            return Scaffold();
          }
        },
      ),
    );
  }
Share:
1,105
Justin Erswell
Author by

Justin Erswell

By Day: I am the CTO for Travelfund.co.uk Ltd. By Night: I am an Apple geek, food lover, imbiber of good wine and husband.

Updated on January 01, 2023

Comments

  • Justin Erswell
    Justin Erswell over 1 year

    I am crafting a new app and saving the response from a REST API call to a Hive box, which is successful (as far as I know). What I am trying to do in my main.dart is check if the value for token is set in Hive and if it is load an alternative view other than the login view.

    My main.dart

    import 'package:flutter/material.dart';
    import 'package:hive_flutter/hive_flutter.dart';
    import 'package:path_provider/path_provider.dart' as path_provider;
    import 'package:myapp/model/user_model.dart';
    import 'package:myapp/views/login_view.dart';
    import 'package:myapp/views/project_view.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      final appDocsDir = await path_provider.getApplicationDocumentsDirectory();
      Hive.init(appDocsDir.path);
      Hive.registerAdapter(UserModelAdapter());
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      State<PocketPolarix> createState() => _PocketPolarixState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        final user = Hive.box('user');
        return MaterialApp(
          title: 'Startup Name Generator',
          theme: ThemeData(
            appBarTheme: const AppBarTheme(
              backgroundColor: Color(0xFF2036B8),
              foregroundColor: Colors.white,
            ),
          ),
          home: FutureBuilder(
            future: Hive.openBox('user'),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text(snapshot.error.toString());
                } else {
    
                  Hive.openBox('user');
                  if (user.get('token') != null) {
                    return const ProjectView();
                  } else {
                    return const LoginView();
                  }
    
                }
              } else {
                return Scaffold();
              }
            },
          ),
        );
      }
    
      @override
      void dispose() {
        Hive.close();
        super.dispose();
      }
    

    The code is failing at the second if statement where I check to see if Hive.box('user').get('token') != null what I keep getting is the following error.

    throw HiveError('Box not found. Did you forget to call Hive.openBox()?'); as you can see from the code however, I am opening the box.

    I am new to Dart and Flutter and Hive for that matter so a helping hand here would be great, thanks!