I get a weird error when trying to initialize Hive - flutter

Error: Unhandled Exception: HiveError: You need to initialize Hive or provide a path to store the box.
Essentially I have these in my dependencies so everything should be good.
hive: ^1.4.4+1
hive_flutter: ^0.3.1
path_provider: ^1.6.27
I also have import 'package:hive/hive.dart';
and
import 'package:path_provider/path_provider.dart'; in the file
So I just have
void doSomething() async {
final documentDirectory = await getApplicationDocumentsDirectory();
Hive.init(documentDirectory.path);
}
called.
I do not understand. I think I've done everything correct. Let me know if you need something else.

Hive needs to be initialized when it runs on Android or iOS, therefore you can use a function like this:
Future<Box> openHiveBox(String boxName) async {
if (!kIsWeb && !Hive.isBoxOpen(boxName))
Hive.init((await getApplicationDocumentsDirectory()).path);
return await Hive.openBox(boxName);
}
You'll need to import path_provider in order to access getApplicationDocumentsDirectory()

Try the following code on the main function of your flutter application:
import 'package:path_provider/path_provider.dart';
import 'package:hive/hive.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory = await getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
}

Currently, path_provider doesn't support WEB. You can see it here: path_provider.
You have to use another directory for WEB. If you are using BLOC as a state management, you could do something like this:
if (!kIsWeb) {
// if android or tablet
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: await getApplicationDocumentsDirectory(),
);
} else {
// if web
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: HydratedStorage.webStorageDirectory,
);
}

I got this error because of a typo:
await Hive.initFlutter;
should've been
await Hive.initFlutter();

I guess you are getting this issue because you are not awaiting the initFlutter.
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
Future<void> yourFunction() async {
final dbDir = await path_provider.getApplicationDocumentsDirectory();
// init hive
await Hive.initFlutter(dbDir.path);
await openYourBox();
}

I think you should await your init method.

Actually you don't need use HydratedStorage to initialize Hive on web:
import 'package:hive/src/hive_impl.dart';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
initializeHive()async{
//Use HiveImpl() to ensure you don't have conflicting Hive boxes.
HiveInterface _hive = HiveImpl();
if (kIsWeb) {
await _hive.openBox('yourBoxName');
} else {
var dir = await getApplicationDocumentsDirectory();
_hive.init(dir.path);
await _hive.openBox('yourBoxName');
}
}
If you're using Flutter on web, you don't need to initialize Hive and neither provider a path to box, only if you're using it on mobile.

Related

Save image into gallery in Flutter

I try to save an image to gallery from a chat. I utilise for that gallery_saver package that does not helpfull. Please advise a proven package to save image into gallery. Or suggest how to fix the issue with method implementation.
void _saveNetworkImage(String url) async {
try {
GallerySaver.saveImage(url).then<void>((bool? success) {
if (success ?? false) {
GetIt.I
.get<NotificationService>()
.showSnackBar(context, S.current.image_saved_to_gallery);
} else {
GetIt.I
.get<NotificationService>()
.showSnackBar(context, S.current.error_image_saving_to_gallery);
}
}).onError((error, stackTrace) {
GetIt.I
.get<NotificationService>()
.showSnackBar(context, S.current.error_image_saving_to_gallery);
});
} catch (e) {
GetIt.I
.get<NotificationService>()
.showSnackBar(context, S.current.error_image_saving_to_gallery);
rethrow;
}
}
You can use path_provider package(link) for getting the local storage data and dio(link) or http(link) to get and save the image to the local storage.
Here's an example:
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
var response = await http.get(imgUrl);
Directory tempDirectory = await getApplicationDocumentsDirectory();
File file = File(join(tempDirectory.path, 'image.png'));
file.writeAsBytesSync(response.bodyBytes);
Also, there's another package called image_gallery_saver(link) that makes saving images an easy task. You can checkout there package because we have to initially setup for some files. After that you can use this method to save image to the gallery.
_save() async {
var response = await Dio().get(
"https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a62e824376d98d1069d40a31113eb807/838ba61ea8d3fd1fc9c7b6853a4e251f94ca5f46.jpg",
options: Options(responseType: ResponseType.bytes));
final result = await ImageGallerySaver.saveImage(
Uint8List.fromList(response.data),
quality: 60,
name: "hello",
);
print(result);
}

I want to add export and import to my application. My database is hive flutter. How?

I want to add export and import database to my application. My database is hive flutter. I tried several methods but it didn't work
ElevatedButton(onPressed: () async{
final String? pathHive=Hive.box<Cart>(cartBoxName).path;
Directory dir=Directory('/storage/emulated/0/Download');
await File(pathHive!).copy('$dir/backup.hive');
}
it didn't work
you can use those methods in order to import/export a backup file for your Hive box in your flutter app:
import 'dart:io';
import 'package:hive/hive.dart';
Future<void> backupHiveBox<T>(String boxName, String backupPath) async {
final box = await Hive.openBox<T>(boxName);
final boxPath = box.path;
await box.close();
try {
File(boxPath).copy(backupPath);
} finally {
await Hive.openBox<T>(boxName);
}
}
Future<void> restoreHiveBox<T>(String boxName, String backupPath) async {
final box = await Hive.openBox<T>(boxName);
final boxPath = box.path;
await box.close();
try {
File(backupPath).copy(boxPath);
} finally {
await Hive.openBox<T>(boxName);
}
}
The concept over it, is that open the Hive box first (if it's already open then you can just get its instance ), Then, using dart:io we can export/import a File with the path of the Hive Box that we got with box.path.
And make sure that the box should be closed when you make the copying operation into/from a file, after that you can open it again.

Flutter - Local files importation

i would like to import in my flutter application, files from "Files" and "Photos" default ios/android/macos applications.
Have you got any solution to do that ?
Thank you
See this documentation: https://docs.flutter.dev/cookbook/persistence/reading-writing-files
add to pubspec (https://pub.dev/packages/path_provider):
path_provider: ^2.0.11
import package:
import 'package:path_provider/path_provider.dart';
Find local path:
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
create reference:
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/counter.txt');
}
read data:
Future<int> readCounter() async {
try {
final file = await _localFile;
// Read the file
final contents = await file.readAsString();
return int.parse(contents);
} catch (e) {
// If encountering an error, return 0
return 0;
}
}
You can use image_picker package to access user's photos with the required permissions;
iOS
Android
You can use the flutter File Picker package.
https://pub.dev/packages/file_picker

How to save video to phone gallery - Dio/Flutter

I'm trying to save the video in the phone gallery (downloaded using dio package) To get the path, I'm using path provider package but unable to save it in the phone gallery
Here is my code
void downloadVideo() async {
var dir = await getExternalStorageDirectory();
final dio = Dio();
dio.download(
'video_url',
'${dir!.path}/video.mp4', // saving path, I'm trying to save it in phone gallery
onReceiveProgress: (actualBytes, totalBytes){
var percentage = actualBytes/totalBytes*100;
}
);
}
Note:- I'm aware of gallery_saver package but I need to achieve this using dio and path provider
So you already have the saving directory. You can use plugins like image_gallery_saver and gallery_saver to save your downloaded video to the gallery.
If you use image_gallery_saver, the saving code would be similar to this:
await ImageGallerySaver.saveFile(finalVideoPath);
And don't forget to delete the video in the download path after saving the video successfully to the gallery.
Final code:
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/widgets.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
Future<void> downloadVideo() async {
final appDocDirectory = await getAppDocDirectory();
final finalVideoPath = join(
appDocDirectory.path,
'Video-${DateTime.now().millisecondsSinceEpoch}.mp4',
);
final dio = Dio();
await dio.download(
'video_url',
finalVideoPath,
onReceiveProgress: (actualBytes, totalBytes) {
final percentage = actualBytes / totalBytes * 100;
},
);
await saveDownloadedVideoToGallery(videoPath: finalVideoPath);
await removeDownloadedVideo(videoPath: finalVideoPath);
}
Future<Directory> getAppDocDirectory() async {
if (Platform.isIOS) {
return getApplicationDocumentsDirectory();
}
return (await getExternalStorageDirectory())!;
}
Future<void> saveDownloadedVideoToGallery({required String videoPath}) async {
await ImageGallerySaver.saveFile(videoPath);
}
Future<void> removeDownloadedVideo({required String videoPath}) async {
try {
Directory(videoPath).deleteSync(recursive: true);
} catch (error) {
debugPrint('$error');
}
}

path_provider: Unhandled Exception: Null check operator used on a null value

I have a problem while working with pat_provider.
Error:
Unhandled Exception: Null check operator used on a null value
Code:
void main() async {
final appDocumentDirectory =
await path_provider.getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
runApp(MyApp());
}
For more, I am using the non-nullsafety app, Right now I want to take the path to hive. what would you advise in such a case. Or should I downgrade the path_provider version?
Just add two lines: import material.dart and add WidgetsFlutterBinding.ensureInitialized();
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory =
await path_provider.getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
runApp(MyApp());
}
Resolved! I was doing hive the old way. The program worked when I called Hive.initFlutter(), not Hive.init(). By the way,
import 'package: hive_flutter / hive_flutter.dart';
and
import 'package: hive / hive.dart';
Don't forget to import both,
Current code:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
runApp(CoozinCustomerApp());
}