Flutter dart export hive saved data to file to retrieve later

1,789

There is not a "out-of-the-box" solution for that as far as I know. It depends a lot on your use case of how you want to do that (since there are many ways). For a complete example of how I did that for my app, you can take a look here: https://github.com/Kounex/obs_blade/blob/master/lib/views/settings/logs/log_detail/log_detail.dart (I made use of the share package in order to easily export it - but that's not necessary)

Flutter also has its own documentation on reading and writing files (https://flutter.dev/docs/cookbook/persistence/reading-writing-files) - I will add some information to round it up:

Storage location


First of all we have to think about where to store the "backup file". Flutter exposes common paths on its own which you can make use of (additionally the path_provider package gives you more flexibility). If you want this backup file to be temporarily, you can for example use:

Directory.systemTemp;

The documentation states: "This is the directory provided by the operating system for creating temporary files and directories in." The OS will make sure to delete them in different occasions so you don't have to worry about it. You can also create additional directories inside this temp directory to make it more distinguishable, like:

Directory.systemTemp.createTemp('my_app');

IMPORTANT: this applies to non-sensitive data. If whatever you are processing contains sensitive data (like names, addresses etc.), you have to ensure data security / data privacy. In such cases I would make use of the path_provider package as mentioned earlier and create those files in the documents directory (getApplicationDocumentsDirectory()) and make sure they are deleted immediately after usage / export. Even encrypting the content may be a good idea - but I'm not diving into this here.

File mangagement


Once we know where to store the file, we just need to create them. Chapter 3 and 4 of the flutter documentation earlier exactly states how to do that, so I'm rather focusing on what to write.

A common and very convenient way to compose your data is JSON. Flutter also has documentation for that: https://flutter.dev/docs/development/data-and-backend/json

Since you are using Hive, you probably already have classes representing entries in your boxes and you could easily just add the toJson() function where you return a Map<String, dynamic> (as seen in the documentation) and you can use that to finally write the needed information into a file.

Based on your Hive class, this is how to adjust it in otder to serialize it correctly:

import 'package:hive/hive.dart';

part 'product.g.dart';

@HiveType(typeId: 0)
class Product extends HiveObject{
  @HiveField(0)
  String itemName;

  @HiveField(1)
  String barCode;

  @HiveField(2)
  String bcType;

  Product(this.itemName, this.barCode, this.bcType);

  /// This function will automatically be used by the [jsonEncode()] function internally
  Map<String, dynamic> toJson() => {
    'itemName': this.itemName,
    'barCode': this.barCode,
    'bcType': this.bcType,
  }
}

A small example implementation could look like this:

Future<File?> _createBackupFile() async {
  /// This example uses the OS temp directory
  File backupFile = File('${Directory.systemTemp.path}/backup_barcode.json');

  try {
    /// barcodeBox is the [Box] object from the Hive package, usually exposed inside a [ValueListenableBuilder] or via [Hive.box()]
    backupFile = await backupFile.writeAsString(jsonEncode(barcodeBox.values));

    return backupFile;
  } catch (e) {
    // TODO: handle exception
  }
}

This will save the JSON representation of your Hive box inside the temporary OS directory. You can swap the directory with whatever suits you best (on Android for example on the external storage for easier accessibility).

Now you have to think about how and when to trigger this. You can do this manually by triggering a button press for example or automatically after a certain action (like adding a new barcode) and choose a way that works for you to access the file. As stated earlier, saving the file somewhere easily accessible like the external storage on Android or making use of the share package are possible solutions.

Share:
1,789
Hendrik
Author by

Hendrik

Updated on December 20, 2022

Comments

  • Hendrik
    Hendrik over 1 year

    I am developing a barcode app and save the data to hive. What I need to know is there a way to export the saved hive database to a backup file and be able to retrieve it for instance if the app crashed or your phone is lost. This is for blind accessibility. Want to export the data to a file that I can save to my pc to store and if something happens I do not have to scan all the products again to build the database. If hive can not do this can someone point me in a direction of which flutter dart database can do this. Thank you

    Ok the answer did not work for me. Here is a copy of my model file

        import 'package:hive/hive.dart';
    
        part 'product.g.dart';
        @HiveType(typeId: 0)
        class Product extends HiveObject{
          @HiveField(0)
          String itemName;
          @HiveField(1)
          String barCode;
          @HiveField(2)
          String bcType;
    
          Product(this.itemName, this.barCode, this.bcType);
        }
    

    Then I call my box like var box = Hive.box('products');

    How to encode this to json for saving?

    I use the next

        Future<File> _createBackupFile() async {
          /// This example uses the OS temp directory
    

    File backupFile = File('${Directory.systemTemp.path}/backup_barcode.json');

          try {
            /// barcodeBox is the [Box] object from the Hive package, usually exposed inside a [ValueListenableBuilder] or via [Hive.box()]
        var barcodeBox = Hive.box<Product>('products');
           backupFile = await backupFile.writeAsString(jsonEncode(barcodeBox.values));
    
            return backupFile;
          } catch (e) {
            // TODO: handle exception
        print(e);
          }
        }