I am crafting a new app and saving the response from a REST API call to a Hive box, which is successful (as far as I know). What I am trying to do in my main.dart is check if the value for token is set in Hive and if it is load an alternative view other than the login view.
My main.dart
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import 'package:myapp/model/user_model.dart';
import 'package:myapp/views/login_view.dart';
import 'package:myapp/views/project_view.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final appDocsDir = await path_provider.getApplicationDocumentsDirectory();
Hive.init(appDocsDir.path);
Hive.registerAdapter(UserModelAdapter());
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<PocketPolarix> createState() => _PocketPolarixState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
final user = Hive.box('user');
return MaterialApp(
title: 'Startup Name Generator',
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF2036B8),
foregroundColor: Colors.white,
),
),
home: FutureBuilder(
future: Hive.openBox('user'),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
Hive.openBox('user');
if (user.get('token') != null) {
return const ProjectView();
} else {
return const LoginView();
}
}
} else {
return Scaffold();
}
},
),
);
}
@override
void dispose() {
Hive.close();
super.dispose();
}
The code is failing at the second if
statement where I check to see if Hive.box('user').get('token') != null
what I keep getting is the following error.
throw HiveError('Box not found. Did you forget to call Hive.openBox()?');
as you can see from the code however, I am opening the box.
I am new to Dart and Flutter and Hive for that matter so a helping hand here would be great, thanks!
CodePudding user response:
Part 1 of the issue is that you were trying to access user before opening. Secondly, I believe you need to check if the snapshot.hasData
before proceeding with any operation i.e.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF2036B8),
foregroundColor: Colors.white,
),
),
home: FutureBuilder(
future: Hive.openBox<YourUserModelBox>('user'),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else if (snapshot.hasData) {
if (snapshot.data is YourUserModelBox) {
final user = snapshot.data as YourUserModelBox;
if (user.get('token') != null) {
return const ProjectView();
} else {
return const LoginView();
}
} else {
Scaffold();
}
}
} else {
return Scaffold();
}
},
),
);
}
CodePudding user response:
The problem is with the first line of code in your build
function. You're trying to get the user
box from Hive without opening it first. Here is what can you do instead:
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF2036B8),
foregroundColor: Colors.white,
),
),
home: FutureBuilder<Box>(
future: Hive.openBox('user'),
builder: (BuildContext context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
if (snapshot.data?.get('token') != null) {
return const ProjectView();
} else {
return const LoginView();
}
}
} else {
return Scaffold();
}
},
),
);
}