I want to open a Hive box based on the current logged in user. To do this I open a box on log in with the user’s uid and close all boxes when logging out. The uid is stored inside app preferences for later use.
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User? user = result.user;
prefs!.setString(AppConstants.kBoxPreferenceKey, user!.uid);
await Hive.openBox(user.uid);
return user;
} catch (error) {
print(error.toString());
return null;
}
}
Future signOut() async {
prefs!.remove(AppConstants.kBoxPreferenceKey);
await Hive.close();
try {
return await _auth.signOut();
} catch (error) {
print(error.toString());
return null;
}
}
After this I have a Change Notifier that handles the local database
class CardsDataBase extends ChangeNotifier {
late Box _myBox;
Box get myBox => _myBox;
CardsDataBase() {
getFolderModels();
// This isn't final, ıt's here just to make sure I have the correct box name from prefs before doing anything else
}
void getFolderModels() {
String boxName = prefs!.getString(AppConstants.kBoxPreferenceKey)!;
_myBox = Hive.box(boxName);
notifyListeners();
}
void deleteFolder(String folderName) {
String uid = prefs!.getString(AppConstants.kBoxPreferenceKey)!;
_myBox = Hive.box(uid);
_myBox.delete(folderName);
notifyListeners();
}
void updateDataBase(String listName, List listContent) {
_myBox = Hive.box(prefs!.getString(AppConstants.kBoxPreferenceKey)!);
_myBox.put(listName, listContent);
notifyListeners();
}
}
The problem occurs inside the library screen where I show the folders from myBox. It works fine and updates as expected until I log out and log back in with the same or a different account.
class LibraryScreen extends StatefulWidget {...}
class _LibraryScreenState extends State<LibraryScreen> {
@override
Widget build(BuildContext context) {
final provider = Provider.of<CardsDataBase>(context);
Iterable listOfKeysFromBox = provider.myBox.keys; //error: Box has already been closed
List<FolderWidget> folderWidgetsList = listOfKeysFromBox.map((e)=>
FolderWidget(folderName: e, folderLocation: FolderLocation.downloaded, folderContents: provider.myBox.get(e))
).toList();
List<StatelessWidget> listForDownloadedColumn = [
const Text('Downloaded Folders',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700)),
const MyDivider(),
];
listForDownloadedColumn.addAll(folderWidgetsList);
return Scaffold(...)
}
I don’t understand why I don’t receive the new box I opened on sign in, when testing the values inside CardsDataBase
I see that they are indeed the correct values and that the _myBox
is the correct box.
3