You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web端Sqflite CRUD操作依赖配置错误求助

Flutter SQLite CRUD 跨平台适配问题解决

问题场景

学习Flutter时创建my_diary_using_sqflite项目,练习SQLite数据库CRUD操作,在适配sqflite、sqflite_common_ffi、sqflite_common_ffi_web三个包时遇到报错。

首次报错(Chrome运行提交笔记时)

Error: Bad state: databaseFactory not initialized
databaseFactory is only initialized when using sqflite. When using sqflite_common_ffi
You must call databaseFactory = databaseFactoryFfi; before using global openDatabase API

pubspec.yaml 依赖配置

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  sqflite: ^2.3.3
  intl: ^0.19.0
  path_provider: ^2.1.3
  sqflite_common_ffi: ^2.3.3
  sqflite_common_ffi_web: ^0.4.3+1

修改main.dart后的报错

修改main.dart初始化databaseFactoryFfi后,Web端出现白屏,报错:

Rejecting promise with error: Unsupported operation: Unsupported on the web, use sqflite_common_ffi_web

相关代码

note_repository.dart(CRUD实现)

import 'package:my_diary_using_sqflite/Models/note.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class NotesRepository {
  static const _dbName = 'notes_database.db';
  static const _tableName = 'notes';

  static Future<Database> database() async {
    return openDatabase(
      join(await getDatabasesPath(), _dbName),
      onCreate: (db, version) {
        return db.execute(
            'CREATE TABLE $_tableName(id INTEGER PRIMARY KEY, title TEXT, description TEXT, createdAt TEXT)');
      },
      version: 1,
    );
  }

  static insert({required Note note}) async {
    print("Finally entering inserted function");
    final db = await database();
    await db.insert(_tableName, note.toMap());
  }

  static Future<List<Note>> getNotes() async {
    final db = await database();
    final List<Map<String, dynamic>> maps = await db.query(_tableName);

    return List.generate(maps.length, (i) {
      return Note(
          id: maps[i]['id'] as int,
          title: maps[i]['title'] as String,
          description: maps[i]['description'] as String,
          createdAt: DateTime.parse(maps[i]['createdAt']));
    });
  }
}

修改后的main.dart

import 'package:flutter/material.dart';
import 'package:my_diary_using_sqflite/Screens/home_screen.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  sqfliteFfiInit();
  databaseFactory = databaseFactoryFfi;
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "My Diary",
        home: Home_Screen());
  }
}

解决方案

问题核心是未针对Web/桌面/移动端配置对应的数据库工厂,且数据库路径处理未适配Web平台,调整如下:

1. 平台差异化初始化数据库工厂

修改main.dart,根据当前运行平台选择对应的databaseFactory:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:my_diary_using_sqflite/Screens/home_screen.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 根据平台选择数据库工厂
  if (kIsWeb) {
    databaseFactory = databaseFactoryFfiWeb;
  } else {
    sqfliteFfiInit();
    databaseFactory = databaseFactoryFfi;
  }
  
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "My Diary",
        home: Home_Screen());
  }
}

2. 适配不同平台的数据库路径

修改NotesRepository中的数据库路径处理逻辑,Web平台无需拼接系统路径:

import 'package:flutter/foundation.dart';
import 'package:my_diary_using_sqflite/Models/note.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class NotesRepository {
  static const _dbName = 'notes_database.db';
  static const _tableName = 'notes';

  static Future<Database> database() async {
    String dbPath;
    if (kIsWeb) {
      // Web端直接使用数据库名称
      dbPath = _dbName;
    } else {
      // 移动端/桌面端拼接系统存储路径
      dbPath = join(await getDatabasesPath(), _dbName);
    }

    return openDatabase(
      dbPath,
      onCreate: (db, version) {
        return db.execute(
            'CREATE TABLE $_tableName(id INTEGER PRIMARY KEY, title TEXT, description TEXT, createdAt TEXT)');
      },
      version: 1,
    );
  }

  static insert({required Note note}) async {
    print("Finally entering inserted function");
    final db = await database();
    await db.insert(_tableName, note.toMap());
  }

  static Future<List<Note>> getNotes() async {
    final db = await database();
    final List<Map<String, dynamic>> maps = await db.query(_tableName);

    return List.generate(maps.length, (i) {
      return Note(
          id: maps[i]['id'] as int,
          title: maps[i]['title'] as String,
          description: maps[i]['description'] as String,
          createdAt: DateTime.parse(maps[i]['createdAt']));
    });
  }
}

说明

  • Web平台:使用sqflite_common_ffi_web提供的databaseFactoryFfiWeb,数据库存储在浏览器IndexedDB中,无需系统路径拼接。
  • 桌面/移动端:使用sqflite_common_ffi(桌面)或原生sqflite(移动端),通过getDatabasesPath()获取系统默认存储路径。

内容的提问来源于stack exchange,提问作者Laksh Ahir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:14:55