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
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!It seems like the issue is with how you are retrieving the
LocalDatabase
object from Hive. When you calllocalDatabase.add(databaseObject)
you are actually adding a newLocalDatabase
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 ofBoxes.getSavedDatabase()
. ThegetAt()
method retrieves the object at the specified index in the box, so callinggetAt(0)
will give you the first (and in this case, the only)LocalDatabase
object in the box.And this is how you should retrieve the
LocalDatabase
object from Hive:So essentially, by using
putAt()
instead ofadd()
, you are updating the existingLocalDatabase
object in the box instead of adding a new one every time.You should mark all fields as HiveField (whichever is needed to save locally) even if they are custom objects and extending hive class.