hive icon indicating copy to clipboard operation
hive copied to clipboard

Unhandled Exception: FileSystemException: Cannot create file, path

Open mdrideout opened this issue 5 years ago • 11 comments

Steps to Reproduce Upgraded previously working app using HiveDB to Hive 1.2.0

  • https://github.com/mdrideout/flutter_hive_provider_example

Error

Syncing files to device iPhone 11 Pro Max...
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: FileSystemException: Cannot create file, path = '/Users/matt/Library/Developer/CoreSimulator/Devices/03D89D69-AF9B-4C27-B92E-52324FE97F34/data/Containers/Data/Application/D0964550-86ED-43BE-A833-41BE76271E58/Documents/contactsbox.hive' (OS Error: No such file or directory, errno = 2)
#0      _File.create.<anonymous closure> (dart:io/file_impl.dart:265:9)
#1      _rootRunUnary (dart:async/zone.dart:1134:38)
#2      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#3      _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#4      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#5      Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#6      Future._completeWithValue (dart:async/future_impl.dart:524:5)
#7      Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:554:7)
#8      _rootRun (dart:async/zone.dart:1126:13)
#9      _CustomZone.run (dart:async/zone.dart<…>
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: FileSystemException: Cannot create file, path = '/Users/matt/Library/Developer/CoreSimulator/Devices/03D89D69-AF9B-4C27-B92E-52324FE97F34/data/Containers/Data/Application/D0964550-86ED-43BE-A833-41BE76271E58/Documents/contactsbox.hive' (OS Error: No such file or directory, errno = 2)
#0      _File.create.<anonymous closure> (dart:io/file_impl.dart:265:9)
#1      _rootRunUnary (dart:async/zone.dart:1134:38)
#2      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#3      _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#4      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#5      Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#6      Future._completeWithValue (dart:async/future_impl.dart:524:5)
#7      Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:554:7)
#8      _rootRun (dart:async/zone.dart:1126:13)
#9      _CustomZone.run (dart:async/zone.dart<…>

#Code sample main.dart

import 'package:flutter/material.dart';
import 'package:flutter_hive_example/models/contact.dart';
import 'package:flutter_hive_example/screens/add_contact_screen.dart';
import 'package:provider/provider.dart';
import 'package:flutter_hive_example/models/contact_data.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_hive_example/screens/contacts_screen.dart';

void main() {
  Hive.registerAdapter(ContactAdapter(), 0);
  runApp(MyApp());
}

Future _initHive() async {
  var dir = await getApplicationDocumentsDirectory();
  Hive.init(dir.path);
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (context) => ContactsData(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        initialRoute: '/',
        routes: {
          '/': (context) => FutureBuilder(
                future: _initHive(),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    if (snapshot.error != null) {
                      print(snapshot.error);
                      return Scaffold(
                        body: Center(
                          child: Text('Error initializing hive data store.'),
                        ),
                      );
                    } else {
                      return ContactsScreen();
                    }
                  } else {
                    return Scaffold();
                  }
                },
              ),
          '/AddContactScreen': (context) => AddContactScreen(),
        },
      ),
    );
  }
}

contact.dart

/**
 * Our contact data model
 */

import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';

part 'contact.g.dart';

@HiveType() // use Hive to generate a type adapter
class Contact {
  // Define variables

  @HiveField(0)
  final String name;

  @HiveField(1)
  final String phone;

  @HiveField(2)
  final String email;

  // Constructor
  Contact({@required this.name, this.phone, this.email});
}

contact_data.dart

/**
 * Manages the data for our contacts
 */

import 'package:flutter/foundation.dart';
import 'contact.dart';
import 'package:hive/hive.dart';

class ContactsData extends ChangeNotifier {
  // Name our hive box for this data
  String _boxName = "contactsBox";

  // Initialize our list of contacts
  List<Contact> _contacts = [];

  /// Get Contacts
  /// Gets all contacts from the hive box and loads them into our state List
  void getContacts() async {
    var box = await Hive.openBox<Contact>(_boxName);

    // Update our provider state data with a hive read, and refresh the ui
    _contacts = box.values.toList();
    notifyListeners();
  }

  /// Get Contact
  /// Retrieves a specific contact from our state
  Contact getContact(index) {
    return _contacts[index];
  }

  /// Contact Count
  /// Returns the length of the contact array
  int get contactCount {
    return _contacts.length;
  }

  /// Add Contact
  /// - Saves contact data to Hive box persistent storage
  /// - Updates our List with the hive data by read
  /// - Notifies listeners to update the UI, which will be a consumer of the _contacts List
  void addContact(Contact newContact) async {
    var box = await Hive.openBox<Contact>(_boxName);

    // Add a contact to our box
    await box.add(newContact);

    // Update our provider state data with a hive read, and refresh the ui
    _contacts = box.values.toList();
    notifyListeners();
  }

  /// Delete Contact
  /// - Deletes the contact from Hive
  /// - Updates our List from Hive
  /// - Notifies listeners to update the UI
  void deleteContact(index) async {
    var box = await Hive.openBox<Contact>(_boxName);

    print("Box Keys: " + box.keys.toList().toString());
    print("Deleting Index " +
        index.toString() +
        " which has a box key value of: " +
        box.keys.toList()[index].toString());

    // Get key of box we want to delete
    var boxKey = box.keys.toList()[index];

    // Delete the contact from the box
    await box.delete(boxKey);

    // Update our provider state data with a hive read, and refresh the ui
    _contacts = box.values.toList();
    notifyListeners();
  }
}

Version

  • Platform: iOS, Android, Mac, Windows, Linux, Web
  • Flutter version: Flutter 1.12.13+hotfix.5 • channel stable
  • Hive version: 1.2.0

mdrideout avatar Dec 22 '19 17:12 mdrideout

Thanks, I'm trying to run your code.

Edit: It works fine on Android and I currently don't have an iOS device to test on. Do you see this issue also on Android devices?

simc avatar Dec 22 '19 17:12 simc

That error was on the iOS simulator on Mac (iPhone 11 Pro Max, Software Version 13.3)

More Tests (all of these are fresh install, no previous version of app installed)

  • Works fine on Android emulator on Mac (fresh install, no previous version of app installed)
  • Works fine on real iOS device in connected debug mode (iPhone SE Software 13.3)
  • Works fine on real Android device connected in debug mode
  • works fine on iOS simulator (iPhone 8 Software Version 13.3)

Deleted App & Tested Again On Simulator iPhone 11 Pro Max I tried uninstalling the app, and then testing again on the iPhone 11 Pro Max simulator and it worked fine!

I am developing 2 apps with very similar hive structure and had the same error message on both of them.

Solution Uninstalling the previously installed version of the app, then doing a fresh "run" from Android Studio fixed the issue.

Potential 1.1.1 -> 1.2.0 Upgrade / Downgrade Issue

iOS Simulator

  • If I downgrade to 1.1.1, run the app (without uninstalling it from device), I encounter the error again.
  • If I uninstall, then run, no error.
  • If the app with hive version 1.1.1 was installed and I update to 1.2.0 and run without uninstalling from device, I encounter the error again.
  • similarly, if I uninstall the app first, then run, it works fine

So this appears to be an upgrade / downgrade issue for this version.

Real iOS device

  • Instead of encountering the error in Android Studio's debug output, the device appears to try launching the app, then goes back to the homescreen, then android studio sits in "installing and launching" phase forever, with no error.
  • This can be repeated until I uninstall the app from the device.
  • After uninstalling, the app will launch fine on the next "run"

Android Devices

  • This issue does not appear to impact android devices.

mdrideout avatar Dec 22 '19 18:12 mdrideout

Thank you for your detailed analysis. This is a very weird issue. I'll try to get access to an iOS simulator to reproduce this behavior.

simc avatar Dec 22 '19 19:12 simc

I had the same error on iOS when I wanted to do the version upgrade. The description made by @mdrideout corresponds perfectly to the problem which is also present when upgrading from 1.1.1 to 1.3.0.

huextrat avatar Jan 06 '20 13:01 huextrat

I've the same issue. @leisim if you have a possibility to fix just do it, please.

bl0ck3man avatar Jan 20 '20 07:01 bl0ck3man

@leisim Is it actual for 1.4.1 ?

bl0ck3man avatar Feb 25 '20 20:02 bl0ck3man

I have the same issue on Android emulator for API 29 for the version ^1.4.1+1.

ilyasdirin avatar May 14 '20 21:05 ilyasdirin

Had same exception on Flutter 1.19.0-4.3pre and Hive 1.4.1+1, Android Emulator API level 29 at Hive.openBox

  Dictionary() {
    const file = 'assets/EnRuBig.json';

    Hive.initFlutter().then((value) {
      Hive.openBox<String>(file).then((box) {
        _box = box;

When I changed the box name from the value in "file" (containing slashes, it is also used latter to load data from bundled asset) to simple "EnRuBig" then it worked for me.

maxim-saplin avatar Jul 11 '20 21:07 maxim-saplin

I had the same issue when the box name contained slash in integration tests, IE:

'tests/test_${testName}_${DateTime.now().microsecond}'.

It might be worth to assert that the name does not contain black listed characters or replace those characters.

cedvdb avatar Apr 12 '22 19:04 cedvdb

Could it be related to the non-relative path on iOS : D0964550-86ED-43BE-A833-41BE76271E58 because the app directory ID is changed by the OS for each app session

Tom3652 avatar Feb 16 '23 13:02 Tom3652

Is there any update regarding this issue?

creatorpiyush avatar Nov 02 '23 11:11 creatorpiyush