The box "contacts" is already open and of type Box<Contact> when trying to access Hive database in flutter

5,387

I'm jumping on this thread because I had a hard time trying to figure out how to deal with the deprecated WatchBoxBuilder while using the resocoder's Hive tutorial, and a google search led me here.

This is what I ended up using:

main.dart:

void main() async {
  if (!kIsWeb) { // <-- I put this here so that I could use Hive in Flutter Web
    final dynamic appDocumentDirectory =
        await path_provider.getApplicationDocumentsDirectory();
    Hive.init(appDocumentDirectory.path as String);
  }
  Hive.registerAdapter(ContactAdapter());

  runApp(child: MyApp());
}

and then ContactPage() (note: it's the same as OP's):

Widget _buildListView() {
  return ValueListenableBuilder(
    valueListenable: Hive.box<Contact>('contacts').listenable(),
    builder: (context, Box<Contact> box, _) {
      if (box.values.isEmpty) {
        return Text('data is empty');
      } else {
        return ListView.builder(
          itemCount: box.values.length,
          itemBuilder: (context, index) {
            var contact = box.getAt(index);
            return ListTile(
              title: Text(contact.name),
              subtitle: Text(contact.age.toString()),
            );
          },
        );
      }
    },
  );
}
Share:
5,387
aboodrak
Author by

aboodrak

Updated on December 17, 2022

Comments

  • aboodrak
    aboodrak over 1 year

    I initialized box database in main as follow

    void main() async {
        WidgetsFlutterBinding.ensureInitialized();
        final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
        Hive.init(appDocumentDirectory.path);
        Hive.registerAdapter(ContactAdapter());
        runApp(MyApp());
    }
    

    then I open box in the material app by using FutureBuilder plugin as follows:

      FutureBuilder(
          future: Hive.openBox<Contact>('contacts'),
          builder: (context, snapshot) {
            if(snapshot.connectionState == ConnectionState.done){
              if(snapshot.hasError){
                return Text(snapshot.error.toString() );
              }
              return ContactPage();
            } else {
              return Scaffold();
            }
          }
        ),
    

    and inside ContactPage()

    I create this:-

      ValueListenableBuilder(
                    valueListenable: Hive.box<Contact>('contacts').listenable(),
                    builder: (context,Box<Contact> box,_){
                      if(box.values.isEmpty){
                        return Text('data is empty');
                      } else {
                        return ListView.builder(
                          itemCount: box.values.length,
                          itemBuilder: (context,index){
                            var contact = box.getAt(index);
                            return ListTile(
                              title: Text(contact.name),
                              subtitle: Text(contact.age.toString()),
                            );
                          },
                        );
                      }
                    },
                   )
    

    when I run the application I get the following error

    The following HiveError was thrown while handling a gesture:
    The box "contacts" is already open and of type Box<Contact>.
    

    and when I tried to use the box without opening it, I got error mean the box is not open.

    Do I have to use box without opening it inside ValueListenableBuilder? But then I have to open same box again in the different widget to add data on it.