Flutter + Hive 检查 Future Builder 的框中是不是存在值

Posted

技术标签:

【中文标题】Flutter + Hive 检查 Future Builder 的框中是不是存在值【英文标题】:Flutter + Hive Check if value is present in box in Future BuilderFlutter + Hive 检查 Future Builder 的框中是否存在值 【发布时间】:2021-11-28 05:26:43 【问题描述】:

我正在制作一个新应用程序并将来自 REST API 调用的响应保存到 Hive 框,这是成功的(据我所知)。我在 main.dart 中尝试做的是检查是否在 Hive 中设置了令牌的值,以及它是否加载了登录视图以外的替代视图。

我的 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();
  

代码在第二个if 语句中失败,我在该语句中检查Hive.box('user').get('token') != null 我不断得到的是否是以下错误。

throw HiveError('Box not found. Did you forget to call Hive.openBox()?'); 正如你从代码中看到的那样,我正在打开盒子。

在这方面我是 Dart、Flutter 和 Hive 的新手,所以在这里伸出援助之手会很棒,谢谢!

【问题讨论】:

【参考方案1】:

问题的第 1 部分是您在打开之前尝试访问用户。其次,我认为您需要在进行任何操作之前检查snapshot.hasData 是否为

  @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();
          
        ,
      ),
    );
  

【讨论】:

【参考方案2】:

问题在于build 函数中的第一行代码。您正在尝试从 Hive 获取 user 框,而无需先打开它。您可以这样做:

@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();
        
      ,
    ),
  );

【讨论】:

以上是关于Flutter + Hive 检查 Future Builder 的框中是不是存在值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Flutter future<bool> 检查 Firestore 中是不是存在子集合

Flutter:从 Future 中获取价值的正确方法

Flutter HiveDB 在 FutureBuilder 上使用框

在 Flutter 的流构建器中使用 Future 构建器是正确的

检查 URL 是不是存在于 Flutter 中时出错

Flutter:检查互联网连接并根据输出导航?