skip to Main Content

I have a Flutter app that retrieves a JSON document from a website and then saves it using Hive. I have a LocalDatabase class that extends HiveObject and contains several objects and lists of custom objects.

Here is the code for the LocalDatabase class:

part 'hive_storage.g.dart';

@HiveType(typeId: 0)
class LocalDatabase extends HiveObject {
  @HiveField(0)
  DateTime? lastUpdate;
  
  List<Schulaufgaben>? examDates;
  
  List<AllgemeineTermine>? appointments;
  
  Schulinformationen? schoolInformation;
}

The Schulaufgaben and AllgemeineTermine classes are custom objects that have their own fromJson() and toJson() methods for serialization and deserialization. The LocalDatabase class also has corresponding Hive adapters generated using Hive’s code generation (hive_generator).

I am able to save and retrieve data using Hive while the app is running. However, after restarting the app, all the objects and lists of custom objects in the LocalDatabase object except for lastUpdate are null.

I have properly initialized Hive in my main function as follows:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  Hive.registerAdapter(LocalDatabaseAdapter());
  await Hive.openBox<LocalDatabase>('localDatabase');
  runApp(const MyApp());
}

And here is how I save the LocalDatabase object to Hive after retrieving data from the website:

final localDatabase = Boxes.getSavedDatabase();

final databaseObject = LocalDatabase()
  ..lastUpdate = DateTime.now()
  ..examDates = await _db.getExamDates()
  ..appointments = await _db.getAppointments();

localDatabase.add(databaseObject);

I am not sure why the custom objects and lists of custom objects are not persisted in Hive after restarting the app.

I have also checked that the custom objects and lists of custom objects are properly registered with Hive using Hive.registerAdapter().

I have referred to a similar issue on Stack Overflow (link: Flutter Hive save custom object with list of custom objects gone after restarting app) but the solutions provided there did not work for me. I have also tried using the hive_flutter package for Flutter-specific implementations, but the issue persists.

3

Answers


  1. Chosen as BEST ANSWER

    Because I forgot to add the other fields of my HiveObject, of course only the lastUpdate variable was saved permanently.

    After I also marked the other fields with a @HiveField(), I got an error that I forgot to register an adapter.

    Now I created a separate TypeAdapter for each of my custom data types. This worked for me!


  2. It seems like the issue is with how you are retrieving the LocalDatabase object from Hive. When you call localDatabase.add(databaseObject) you are actually adding a new LocalDatabase object to the Hive box every time the app is restarted, instead of updating the existing one.

    To properly retrieve the LocalDatabase object from Hive, you should call localDatabase.getAt(0) instead of Boxes.getSavedDatabase(). The getAt() method retrieves the object at the specified index in the box, so calling getAt(0) will give you the first (and in this case, the only) LocalDatabase object in the box.

    final localDatabaseBox = await Hive.openBox<LocalDatabase>('localDatabase');
    final databaseObject = LocalDatabase()
      ..lastUpdate = DateTime.now()
      ..examDates = await _db.getExamDates()
      ..appointments = await _db.getAppointments();
    
    localDatabaseBox.putAt(0, databaseObject);
    

    And this is how you should retrieve the LocalDatabase object from Hive:

    final localDatabaseBox = await Hive.openBox<LocalDatabase>('localDatabase');
    final localDatabase = localDatabaseBox.getAt(0);
    

    So essentially, by using putAt() instead of add(), you are updating the existing LocalDatabase object in the box instead of adding a new one every time.

    Login or Signup to reply.
  3. You should mark all fields as HiveField (whichever is needed to save locally) even if they are custom objects and extending hive class.

    @HiveType(typeId: 0)
    class LocalDatabase extends HiveObject {
      @HiveField(0)
      DateTime? lastUpdate;
      @HiveField(1)
      List<Schulaufgaben>? examDates;
      @HiveField(2)
      List<AllgemeineTermine>? appointments;
      
      Schulinformationen? schoolInformation;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search